首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >确定DLL的符号名

确定DLL的符号名
EN

Stack Overflow用户
提问于 2013-10-02 17:00:12
回答 2查看 1.6K关注 0票数 0

我曾经使用过"CPPLoadLibrary“示例(来自Microsoft框架)--好吧,从示例DLL导出符号有两种方法。

  1. 使用.DEF文件从DLL导出符号模块定义(.DEF)文件是一个文本文件,包含描述DLL各种属性的一个或多个模块语句。创建一个.DEF文件并在构建DLL时使用.def文件。使用这种方法,我们可以通过序号而不是名称从DLL导出函数。
  2. 使用__declspec(dllexport) __declspec(dllexport)从DLL导出符号将导出指令添加到对象文件中,因此我们不需要使用.def文件。当试图导出带有修饰的C++函数名时,这种方便是最明显的。

我们有下面的代码。

代码语言:javascript
复制
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“代表什么?谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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

票数 3
EN

Stack Overflow用户

发布于 2013-10-02 17:24:44

要回答您的实际问题,可以使用编译器的TDUMP或类似的工具,或者可以显示可执行文件的导出表的任何其他工具,这样您就可以看到实际导出的名称。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19142564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档