gpt4 book ai didi

c++ - 确定 DLL 的符号名称

转载 作者:行者123 更新时间:2023-11-28 07:23:11 25 4
gpt4 key购买 nike

我曾使用“CPPLoadLibrary”示例(来自 Microsoft All-in-One 框架)好的,有两种从示例 DLL 导出符号的方法。

  1. 使用 .DEF 文件从 DLL 导出符号模块定义 (.DEF) 文件是包含一个或多个模块的文本文件描述 DLL 各种属性的语句。创建一个 .DEF 文件并构建 DLL 时使用 .def 文件。使用这种方法,我们可以导出从 DLL 中按序号而不是按名称调用函数。
  2. 使用 __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”代表什么?谢谢。

最佳答案

如果您不使用 .DEF 文件,导出名称会根据它们的调用约定进行修饰,以支持导出重载函数。参见 Why can't I GetProcAddress a function I dllexport'ed? :

[T]he decoration scheme varies from architecture to architecture and from calling convention to calling convention. So, for example, if the function is exported from a PPC DLL, you would have to do GetProcAddress(hinst, "..SomeFunction"), but if it is exported from an 80386 DLL as extern "C" __stdcall, you would need GetProcAddress(hinst, "_SomeFunction@8"), but if it's __fastcall you would need GetProcAddress(hinst, "@SomeFunction@8").

What's more, C++ decoration varies from compiler vendor to compiler vendor. A C++ exported function might require GetProcAddress(hinst, "?SomeFunction@@YGXHH@Z") if compiled with the Microsoft C++ compiler, but some other decorated string if compiled with the Borland C++ compiler.

So if you intend people to be able to GetProcAddress for functions and you intend your code to be portable to multiple platforms, or if you intend them to be able to use your DLL from a language other than C/C++ or use a C++ compiler different from Microsoft Visual Studio, then you must export the function by its undecorated name.

参见 The history of calling conventions, part3有关各种名称装饰方案的说明。在这种情况下,该函数使用 __stdcall 调用约定,因此它通过在前面加上一个下划线并附加一个 @ 符号和它需要的参数的字节数来装饰。它需要一个字大小的参数,总共 4 个字节,因此它被装饰为 _GetStringLength2@4

关于c++ - 确定 DLL 的符号名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19142564/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com