Windows 函数的链接错误
我正在尝试测试标准库(kernel32.dll)是否具有其中一项功能。
测试代码片段:
extern void CreateProcessA (void);
int
main (void)
{
CreateProcessA ();
return 0;
}
代码编译和链接如下:
cl /c test.c
link test.obj kernel32.lib
该代码可以用 Visual C++ 很好地编译,但无法链接:
test.obj : error LNK2019: unresolved external symbol _CreateProcessA referenced in function _main
但是函数 CreateProcessA 确实存在于 kernel32.dll 中,你不知道吗?
如何正确链接呢?
PS 我不想运行此代码,只需检查函数是否存在(如果代码编译并链接 - 函数存在)。
I'm trying to test if standard library (kernel32.dll) have one of the function.
Code snippet for test:
extern void CreateProcessA (void);
int
main (void)
{
CreateProcessA ();
return 0;
}
The code compiles and links as follow:
cl /c test.c
link test.obj kernel32.lib
This code can be compiled well with Visual C++, but cannot link:
test.obj : error LNK2019: unresolved external symbol _CreateProcessA referenced in function _main
But function CreateProcessA does exists in kernel32.dll, you no?
How to link it properly?
P.S. I don't want to run this code, just check that function exists (if code compiles and links - function exists).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
要查看该函数是否存在,您使用了
您甚至没有使用正确的原型,因此链接器当然无法找到正确的函数。命名约定完全不适用,CreateProcess 实际上是一个宏(根据
UNICODE
扩展为CreateProcessA
或W
)。(您不需要显式链接
kernel32.lib
,因为cl.exe
默认情况下已完成此操作)而不是自己声明原型,
#include
。To see if the function exists, you use
You didn't even use the right prototype, so of course the linker can't find the correct function. The naming convention is completely off, and CreateProcess is really a macro (that expands to either
CreateProcessA
orW
depending onUNICODE
).(You don't need to link against
kernel32.lib
explicitly as that's already done by default bycl.exe
)Instead of declaring the prototype yourself,
#include <windows.h>
.Kernel32.dll 将函数导出为“CreateProcessA”,请注意缺少的前导下划线。说服链接器使用该导出的唯一方法是链接 kernel32.lib(Windows SDK 提供的导入库)。
然后您将遇到下一个问题,导入库将导出声明为
_CreateProcess@40
。这是__stdcall 调用约定应用的名称修饰。该调用约定是明确设计来捕获您的错误的,您没有正确声明该函数。名称的 @40 部分表示堆栈帧中传递参数所需的字节数。因此,要使其正常工作,您应该
#include
获取正确的函数声明并链接 kernel32.lib 以获取正确的导出名称。Kernel32.dll exports the function as "CreateProcessA", note the missing leading underscore. The only way to convince the linker to use that export is by linking kernel32.lib, an import library supplied by the Windows SDK.
You'll then run into the next problem, the import library declares the export as
_CreateProcess@40
. This is a name decoration applied by the __stdcall calling convention. That calling convention was explicitly designed to catch your mistake, you didn't declare the function properly. The @40 part of the name indicates the number of bytes needed in the stack frame to pass the arguments.So, to make it work you should
#include <windows.h>
to get the proper function declaration and link kernel32.lib to get the proper export name.现在您正在声明您自己的 CreateProcess() 版本。由于您没有提供主体(代码),链接器不知道在哪里检查以找到要执行的函数。
为了从 kernel32.lib 调用 CreateProcess,您需要包含正确的标头。
如果编译器不知道 windows.h,则可能没有正确安装 Windows 平台 SDK。
您还需要链接到正确的库
您还应该阅读有关createprocess的文档,因为它需要大量的参数
您应该在互联网上搜索CreateProcess示例,并且可能考虑切换到c ++,因为您在Windows上
Right now you are declaring your own version of CreateProcess(). Since you did not provide the body (code), the linker doesnt know where to check to find the function to execute.
In order to call CreateProcess from kernel32.lib, you need to include the proper headers
If the compiler doesnt know windows.h then probably Platform SDK for windows isnt installed correctly.
you will also need to link with the proper lib
You should also read the documentation about createprocess since it takes a gazillion of parametetrs
You should search for CreateProcess examples across the interwebs and maybe consider switching to c++ since you're on windows
对于初学者,请为原型放入适当的头文件
,因为这是 Windows 源代码,请为链接器添加 kernel32.lib,删除该原型,因为它不正确。您的main
函数对于您是否正在创建命令行程序或 Windows 程序存在争议 - 如果是后者,则应读取“WinMain'。如果您在 MSDN 中查找函数 'CreateProcess',向下滚动,您将看到“库”,这是告诉您需要链接哪个库才能正常工作的提示。
希望这有帮助,
此致,
汤姆.
For starters, put in a proper header file for the prototypes,
<windows.h>
, as this is a Windows source, add the kernel32.lib for your linker, remove that prototype as it is incorrect. Yourmain
function is debatable as to whether you are creating a command line program or a windows program - if it is the latter, that should read 'WinMain'.If you look in the MSDN for the function 'CreateProcess', scroll down and you will see the 'Library', that is the hint to tell you which library you need to link for it to work properly.
Hope this helps,
Best regards,
Tom.
我认为这是一个坏主意,但如果你想这样做,你需要链接到 kernel32.lib 导出库。
I think this is a bad idea, but if you want to do it, you need to link with the kernel32.lib export library.
您必须包含
windows.h
才能获得正确的原型:您是否有特定原因不想包含
windows.h
?You must include
windows.h
in order to get the correct prototype:Is there a particular reason you don't want to include
windows.h
?使用 MinGW 可以使用“-mwindows”标志。示例:
这将包括 gdi32.a、kernel32.a、user32.a 和 ws2_32.a 等内容。
Using MinGW one can use the "-mwindows" flag. Example:
This will include stuff like gdi32.a, kernel32.a, user32.a and ws2_32.a.