【发布时间】:2013-10-09 04:04:44
【问题描述】:
我使用过“CPPLoadLibrary”示例(来自 Microsoft All-in-One 框架) 好的,有两种方法可以从示例 DLL 中导出符号。
- 使用 .DEF 文件从 DLL 导出符号 模块定义 (.DEF) 文件是包含一个或多个模块的文本文件 描述 DLL 的各种属性的语句。创建一个 .DEF 文件并 构建 DLL 时使用 .def 文件。使用这种方法,我们可以导出 DLL 中的函数按序号而不是按名称。
- 使用 __declspec(dllexport) 从 DLL 导出符号 __declspec(dllexport) 将导出指令添加到目标文件中,所以我们这样做 不需要使用 .def 文件。这种便利在尝试时最为明显 导出修饰的 C++ 函数名称。
所以我们有以下代码。
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”代表什么? 谢谢。
【问题讨论】:
-
它是 __stdcall 调用约定的标准装饰。函数指针声明中的 CALLBACK 宏也指定了 __stdcall。一般来说,使用 LoadLibrary + GetProcAddress 肯定是您要避免的,它太容易出错了。只需让链接器处理它,链接导入库。