0

我有 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

4 回答 4

2

您需要使用extern "C"来防止名称混淆并确保导出函数:

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

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

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”。

于 2012-01-25T11:10:11.837 回答
1

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

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

但是,您的功能仍会受到名称装饰的影响。如果你用__declspec(dllexport)then 导出它,它实际上会用 name 导出_Myfunction@4。如果您希望以真实名称导出它,则需要使用 .def 文件。

但是,仍然有可能您根本没有从 DLL 导出函数。使用Dependency Walker检查它是否被导出,如果是,则以什么名称导出。

于 2012-01-25T11:17:20.037 回答
0

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

于 2012-01-25T11:05:34.183 回答
0

该符号将被装饰,因此它永远不会被调用MyFunction,它更有可能_MyFunction@4。您可以使用诸如dumpbin 之类的东西快速检查这一点。

你可以在这里阅读更多关于重整的信息,如果你想避免重整,你需要使用一个def文件来指定符号名称(或序数)。

于 2012-01-25T13:11:18.630 回答