Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Windows函数的链接错误_C_Windows_Linker_Name Decoration - Fatal编程技术网

C Windows函数的链接错误

C Windows函数的链接错误,c,windows,linker,name-decoration,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 此代码可以用VisualC++编写,但不能链接: test.obj : error LNK2019: unresolved externa

我试图测试标准库(kernel32.dll)是否有一个函数

用于测试的代码段:

extern void CreateProcessA (void);
int
main (void)
{
  CreateProcessA ();
  return 0;
}
代码编译和链接如下:

cl /c test.c
link test.obj kernel32.lib

此代码可以用VisualC++编写,但不能链接:

test.obj : error LNK2019: unresolved external symbol _CreateProcessA referenced in function _main
但是函数CreateProcessA确实存在于kernel32.dll中,您不知道吗

如何正确链接


另外,我不想运行此代码,只需检查函数是否存在(如果代码编译且链接-函数存在)。

若要查看函数是否存在,请使用

dumpbin /exports kernel32.dll | findstr CreateProcess
您甚至没有使用正确的原型,因此链接器当然无法找到正确的函数。命名约定完全关闭,CreateProcess实际上是一个宏(根据
UNICODE
,它可以扩展为
CreateProcessA
W

(您不需要显式地链接到
kernel32.lib
,因为默认情况下,
cl.exe
已经这样做了)


与其自己声明原型,
#include

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

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

#include <windows.h>
int
main (void)
{
  CreateProcess(); // will cause warning due to incorrect parameter list
  return 0;
}
#包括
int
主(空)
{
CreateProcess();//由于参数列表不正确,将导致警告
返回0;
}

您不想包含
windows.h
,有什么特殊原因吗?

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

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

#include <windows.h>
您还应该阅读有关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
);

你应该搜索跨进程的CuraPATE过程实例,也许考虑切换到C++,因为你在Windows

初学者,为原型放上一个正确的头文件,<代码> <代码>,因为这是一个Windows源代码,添加链接器的KNEL32.LIB,删除它的原型,因为它是不正确的。您的

main
函数在创建命令行程序还是windows程序方面存在争议-如果是后者,则应为“”

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

希望这有帮助, 顺致敬意,
Tom.

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

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


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

使用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.

等内容,但您想检查该函数是在编译时还是在运行时存在?我看不出第一个函数有什么用处(见鬼,文档是要读的,不管怎样,如果包含windows.h,如果函数不存在,则会导致编译错误),在第二种情况下,它可能很有用,因为某些函数在每个Windows版本上都不可用。但在这种情况下,它不是C链接-CreateProcess使用stdcall,这意味着名称用用于参数的堆栈字节数修饰-他的声明不包括它。哇!拉里在堆栈溢出上!嗨,拉里!不仅如此,符号还被进一步修饰,前缀为
\uuu imp\uu
。因此,您还需要一个
\uu declspec(dllimport)
来获得正确的命名。当然,这是由
完成的。一段时间以来,我一直在想,您应该如何知道要包含和链接哪些头文件和库文件。嗯,那些MSDN页面又长又枯燥,我很少读到底。谢谢
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