为什么此代码不起作用(请查看详细信息)?

Why doesn't this code work (Please See Details)?

我写了下面的代码(x64 VS 2015):

typedef void(__stdcall *foo)(void* v);
HMODULE hmod = GetModuleHandle(NULL);
foo f = (foo) GetProcAddress(hmod, "_foo0");
f(0);

foo0 定义为:

extern "C" void __stdcall foo0(void* v){int a = 0;}

我已禁用所有优化和安全检查。

我想让代码做的是找到foo0的地址然后调用它。 出于某种奇怪的原因,在 GetModuleHandle() returns 0x00000032 之后调用 GetLastError() 这意味着 ERROR_NOT_SUPPORTED,但它确实 return 我假设的一些非零值是可执行文件的句柄。 GetProcAddress() returns 0x0000000000000000GetLastError() 在它之后调用 returns 0x0000007f 这意味着 ERROR_PROC_NOT_FOUND,但我定义了过程!

为什么会这样? GetProcAddress() 不应该与 GetModuleHandle() 一起使用吗?

应该是:

extern "C" __declspec(dllexport) void foo0(void* v) { int a = 0; }

和:

foo f = (foo)GetProcAddress(hmod, "foo0");
                                  ^^~~~ no need for underline

关于您的 GetLastError 问题,我不确定 - 我想它可能是一些随机值。

代码失败,因为 GetProcAddress 要求提供的符号已从相关模块中导出。也就是说,该符号必须已在 PE 模块的导出 table 中列出。您没有导出符号,因此 GetProcAddress 无法找到它。因此 GetProcAddress returns NULL。如果您想使用 GetProcAddress,则必须导出符号。通过在 .def 文件中命名,或使用 __declspec(dllexport).

其他一些评论:

  1. 您的调用约定似乎不匹配,stdcallcdecl
  2. 您没有执行任何错误检查。对于这些特定功能,您需要检查 return 值。如果这表明函数失败,则调用 GetLastError 以获取扩展错误信息。