Windows功能的链接错误

时间:2010-01-31 13:08:31

标签: c windows linker name-decoration

我正在尝试测试标准库(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中,你没有?

如何正确链接?

P.S。我不想运行此代码,只检查该函数是否存在(如果代码编译和链接 - 函数存在)。

7 个答案:

答案 0 :(得分:8)

要查看该功能是否存在,请使用

dumpbin /exports kernel32.dll | findstr CreateProcess

您甚至没有使用正确的原型,因此链接器当然无法找到正确的功能。命名约定完全关闭,CreateProcess实际上是一个宏(根据CreateProcessA扩展为WUNICODE。)

(您无需明确链接kernel32.lib,因为默认情况下cl.exe已完成此操作

而不是自己宣布原型,#include <windows.h>

答案 1 :(得分:3)

Kernel32.dll将该函数导出为“CreateProcessA”,请注意缺少的前导下划线。说服链接器使用该导出的唯一方法是链接kernel32.lib,这是Windows SDK提供的导入库。

然后您将遇到下一个问题,导入库将导出声明为_CreateProcess@40。这是__stdcall calling convention应用的名称修饰。该调用约定是明确设计用于捕获您的错误,您没有正确声明该函数。名称的@ 40部分表示堆栈帧中传递参数所需的字节数。

因此,要使其工作,您应该#include <windows.h>获取正确的函数声明并链接kernel32.lib以获取正确的导出名称。

答案 2 :(得分:2)

现在您正在声明自己的CreateProcess()版本。由于您没有提供正文(代码),链接器不知道在哪里检查以查找要执行的函数。

为了从kernel32.lib调用CreateProcess,您需要包含正确的标题

#include <windows.h>

如果编译器不知道windows.h,那么很可能没有正确安装适用于Windows的Platform SDK。

您还需要链接正确的lib

#pragma comment(lib, "kernel32.lib")

您还应该阅读有关createprocess的文档,因为它需要大量的参数

BOOL WINAPI CreateProcess(
  __in_opt     LPCTSTR lpApplicationName,
  __inout_opt  LPTSTR lpCommandLine,
  __in_opt     LPSECURITY_ATTRIBUTES lpProcessAttributes,
  __in_opt     LPSECURITY_ATTRIBUTES lpThreadAttributes,
  __in         BOOL bInheritHandles,
  __in         DWORD dwCreationFlags,
  __in_opt     LPVOID lpEnvironment,
  __in_opt     LPCTSTR lpCurrentDirectory,
  __in         LPSTARTUPINFO lpStartupInfo,
  __out        LPPROCESS_INFORMATION lpProcessInformation
);

你应该在interwebs中搜索CreateProcess示例,并且可能因为你在windows上而考虑切换到c ++

答案 3 :(得分:1)

对于初学者,请为原型<windows.h>输入正确的头文件,因为这是一个Windows源代码,为您的链接器添加 kernel32.lib ,删除原型是不正确的。关于您是创建命令行程序还是Windows程序,您的main函数是值得商榷的 - 如果是后者,则应该是“WinMain”。

如果您在MSDN中查找功能“CreateProcess”,请向下滚动,您将看到“库”,这是一个提示,告诉您需要链接哪个库才能使其正常工作。

希望这有帮助, 最好的祝福, 汤姆。

答案 4 :(得分:0)

我认为这是一个坏主意,但如果你想这样做,你需要链接到kernel32.lib导出库。

答案 5 :(得分:0)

您必须包含windows.h才能获得正确的原型:

#include <windows.h>
int
main (void)
{
  CreateProcess(); // will cause warning due to incorrect parameter list
  return 0;
}

您是否有特殊原因想要包含windows.h

答案 6 :(得分:0)

使用MinGW可以使用“-mwindows”标志。例如:

gcc.exe -c -g -MMD -MP -MF build/Debug/MinGW-Windows/newmain.o.d -o build/Debug/MinGW-Windows/newmain.o newmain.c
gcc.exe -o dist/Debug/MinGW-Windows/hwprint_dll build/Debug/MinGW-Windows/newmain.o -mwindows 

这将包括gdi32.a,kernel32.a,user32.a和ws2_32.a等内容。