关于GetProcAddress

时间:2012-01-25 11:03:19

标签: c++ dll getprocaddress

我有MyDll.dll,其功能定义如下

void pascal Myfunction(BOOL);

当我尝试在另一个项目中使用该函数时,我无法使用GetProcAddress()获取该函数的地址。这是我的代码:

void callMyDll()
{
 HINSTANCE hDll;

 hDll=LoadLibrary(_T("MyDll.dll");

 if(hDll!=NULL)
 {
  cout<<"\n DLL Loaded \n";
 }
 else
  cout<<"\n DLL Not loaded\n"

 typedef void (__stdcall *MyFunction)(bool)

 Myfunction mf1 = (MyFunction) GetProcAddress(hDll, "MyFunction");

 if (mf1!=NULL)
  cout<<"\n Function Loaded Successfully \n";
 else
  cout<<"\n Function not loaded \n";

 FreeLibrary(hDll);
}

我的输出为:

DLL Loaded
Function not loaded

但是当我尝试使用像glut32.dll这样的已知DLL及其功能时,它工作正常。

我认为它的功能可能有问题,如

void pascal MyFunction(BOOL);

在这方面有人可以帮助我吗?

4 个答案:

答案 0 :(得分:2)

您需要使用extern "C"来防止名称损坏并确保导出该功能:

extern "C" __declspec(dllexport) void Myfunction(BOOL);

要查看DLL的导出,您可以使用Visual Studio附带的dumpbin.exe实用程序:

dumpbin.exe /EXPORTS MyDll.dll

这将列出所有导出符号的名称。

除此之外,没有指定以下任何一个编译器开关:

Gz __stdcall calling convention: "Myfunction" would be exported as Myfunction@4
Gr __fastcall caling convention: "Myfunction" would be exported as @Myfunction@4

注意:我认为最后一个符号依赖于编译器版本,但仍然不仅仅是“Myfunction”。

答案 1 :(得分:1)

DLL导出过程受名称修改和装饰的影响。长期过时的16位pascal调用约定相当于32位平台上的stdcall

首先,您应该使用extern "C"指定C链接并禁用名称修改。

但是,您的功能仍然受name decoration的约束。如果您使用__declspec(dllexport)导出它,那么它实际上将以名称_Myfunction@4导出。如果您希望以真实名称导出它,则需要使用.def文件。

然而,仍然存在这样的可能性:您根本没有从DLL导出函数。使用Dependency Walker检查是否已导出,如果是,则使用什么名称。

答案 2 :(得分:0)

为什么使用pascal调用约定?也许这会改变符号的名称,如果是这样,你可能需要考虑到这一点。

答案 3 :(得分:0)

符号将被装饰,因此它永远不会被称为MyFunction,更可能是_MyFunction@4。你可以使用像dumpbin这样的东西快速检查一下。

您可以阅读有关修改here的更多信息,如果您想避免修改,则需要使用def文件来指定符号名称(或序数)。