为什么此代码不起作用(请查看详细信息)?
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 0x0000000000000000
和 GetLastError()
在它之后调用 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)
.
其他一些评论:
- 您的调用约定似乎不匹配,
stdcall
和 cdecl
。
- 您没有执行任何错误检查。对于这些特定功能,您需要检查 return 值。如果这表明函数失败,则调用
GetLastError
以获取扩展错误信息。
我写了下面的代码(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 0x0000000000000000
和 GetLastError()
在它之后调用 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)
.
其他一些评论:
- 您的调用约定似乎不匹配,
stdcall
和cdecl
。 - 您没有执行任何错误检查。对于这些特定功能,您需要检查 return 值。如果这表明函数失败,则调用
GetLastError
以获取扩展错误信息。