【发布时间】:2015-09-25 18:34:51
【问题描述】:
我正在尝试从我自己的 DLL 中调用一个函数,但根据 DLL 项目中的调用约定,要么我找不到 ProcAddress,要么我的堆栈已损坏。它非常适合第 3 方 DLL,因此如果那里没有重大问题,我不想更改加载代码本身的任何内容。一个最小的例子:
#include <windows.h>
#include <cstdlib>
#include <iostream>
typedef long (__stdcall* tMyFunction)(int);
int main(int argc, char* argv[]){
HINSTANCE m_dllHandle = LoadLibrary("MyDll.dll");
if (m_dllHandle != NULL){
tMyFunction function = (tMyFunction)GetProcAddress(m_dllHandle, "myFunction");
if (function != NULL){
long value = function(1);
std::cout << value << std::endl;
}else{
std::cout << "GetProcAddress() failed" << std::endl;
}
FreeLibrary(m_dllHandle);
m_dllHandle = NULL;
}else{
std::cout << "LoadLibrary() failed" << std::endl;
}
system("pause");
return EXIT_SUCCESS;
}
在 DLL 中:
extern "C" __declspec(dllexport) long __stdcall myFunction(int a){
return 10;
}
结果:GetProcAddress() 失败
dumpbin /EXPORTS -> _myFunction@4 = _myFunction@4
extern "C" __declspec(dllexport) long __cdecl myFunction(int a){
return 10;
}
结果:“运行时检查失败 #0 - ESP 的值未在函数调用中正确保存。这通常是调用使用一种调用约定声明的函数而使用另一种调用声明的函数指针的结果习俗。” (因为我在加载代码时使用了 __stdcall,在 DLL 中使用了 __cdecl)。
dumpbin /EXPORTS -> _myFunction = _myFunction
在第 3 方 DLL 中,我可以看到,“dumpbin /EXPORTS”只显示
myFunction(没有下划线,没有@4)我可以做些什么来完成同样的事情并且仍然能够使用上面定义的类型(typedef long (__stdcall* tMyFunction)(int);)加载它?我的编译器是“Visual Studio 2013”。
【问题讨论】:
-
您正在导出修饰的名称,但将未修饰的名称传递给
GetProcAddress。 -
我猜是因为符号名称不匹配。也许您可以尝试使用 DEF 文件来指定导出的函数?见msdn.microsoft.com/en-us/library/d91k01sh.aspx
-
仅供参考,
extern C不会停止名称修饰,只会停止 C++ 名称修饰。要完全没有装饰,您需要使用@KingsleyChen 建议的 DEF 文件。
标签: c++ dll visual-studio-2013