我曾经使用过"CPPLoadLibrary“示例(来自Microsoft框架)--好吧,从示例DLL导出符号有两种方法。
我们有下面的代码。
typedef int (_cdecl* LPFNGETSTRINGLENGTH1) (PCWSTR);
typedef int (CALLBACK* LPFNGETSTRINGLENGTH2) (PCWSTR);
LPFNGETSTRINGLENGTH1 lpfnGetStringLength1 = (LPFNGETSTRINGLENGTH1)
GetProcAddress(hModule, "GetStringLength1");
LPFNGETSTRINGLENGTH2 lpfnGetStringLength2 = (LPFNGETSTRINGLENGTH2)
GetProcAddress(hModule, "_GetStringLength2@4");那么,我的问题是如何确定符号的名称才能调用GetProcAddress?在第一种情况下,非常简单,我们从.DEF文件中取这个符号名。但是"_GetStringLength2@4“是什么下划线呢?"@4“代表什么?谢谢。
发布于 2013-10-02 17:07:29
如果不使用.DEF文件,导出名称将根据其调用约定进行修饰,以支持导出重载函数。请参阅为什么我不能GetProcAddress一个我导出的函数?
装饰方案因建筑而异,也因调用约定而异。因此,例如,如果函数是从PPC DLL导出的,则必须执行
GetProcAddress(hinst, "..SomeFunction"),但如果它是从80386 DLL导出为extern "C" __stdcall,则需要GetProcAddress(hinst, "_SomeFunction@8"),但如果它是__fastcall,则需要GetProcAddress(hinst, "@SomeFunction@8")。 此外,编译器厂商的C++装饰也各不相同。如果用Microsoft编译器编译,C++导出函数可能需要GetProcAddress(hinst, "?SomeFunction@@YGXHH@Z"),但如果使用Borland C++编译器编译,则需要一些其他修饰字符串。 因此,如果您希望人们能够为函数提供GetProcAddress,并且您希望您的代码可以移植到多个平台,或者您希望他们能够使用C/C++以外的语言的DLL,或者使用与Microsoft不同的C++编译器,那么您必须通过函数未修饰的名称导出该函数。
有关各种名称装饰方案的说明,请参见调用约定的历史,part3。在本例中,该函数使用__stdcall调用约定,因此它通过在下划线前面加上一个@符号和它接受的参数的字节数来修饰。它需要一个字大小的参数,共计4个字节,因此它被修饰为_GetStringLength2@4。
发布于 2013-10-02 17:24:44
要回答您的实际问题,可以使用编译器的TDUMP或类似的工具,或者可以显示可执行文件的导出表的任何其他工具,这样您就可以看到实际导出的名称。
https://stackoverflow.com/questions/19142564
复制相似问题