GetProcAddress 在 DLL 中找不到函数

GetProcAddress does not find function in DLL

提问人:Sasan 提问时间:8/29/2021 最后编辑:Remy LebeauSasan 更新时间:8/29/2021 访问量:392

问:

我有一个DLL,我想在其中调用一个函数。我使用 Dependency Walker 检查 DLL,得到的结果是:

 void U2U_Test(void)

这是我编写的代码,但返回 NULL:GetProcAddress()

typedef void(*U2U_Test_pointer)();

void  check() {

    HINSTANCE hGetProcIDDLL1 = LoadLibrary(_T("my_dll.dll"));

    if (hGetProcIDDLL1 == NULL)
        return;

    U2U_Test_pointer addr = (U2U_Test_pointer)GetProcAddress(hGetProcIDDLL1, "U2U_Test");

    if (addr == NULL)
        return;

    return addr();
}
C++ getprocaddress 依赖遍历程序

评论

2赞 273K 8/29/2021
你会看到分离的名字。我应该修改导出的名称。
0赞 PaulMcKenzie 8/29/2021
GetProcAddress不会说谎。加载的 DLL 中不存在名为该函数的函数。如果您说确实如此,请尽快联系 Microsoft,因为这是一个会影响数百万个程序的错误。U2U_Test
0赞 WhozCraig 8/29/2021
不相关,但在该功能中也没有意义。函数是 。这应该很简单return addr();voidaddr();
0赞 Sasan 8/29/2021
@S.M.你是对的,我应该使用吗?U2U_Test@@YAXXZ函数名称,它解决了问题。
0赞 Sasan 8/29/2021
@PaulMcKenzie你是对的,GetProcAddress 不会说谎,但我正在寻找我的错误,并在亲爱的 SM 的帮助下。我发现了我的错误。

答:

0赞 QuentinC 8/29/2021 #1

根据使用的约定和编译器,在 DLL 中导出的实际名称可能与在源代码中编写的名称不完全相同。 这种现象通常称为名称装饰或名称篡改。

事实上,只有在以下情况下,您才能保证拥有完全相同的名称

  • 你的编译器符合 C 约定(可能确实如此)
  • 该函数以 C 而不是 C++ 导出。用于指定它。extern "C"
  • 调用约定_cdecl(在函数声明中指定)__cdecl

例如,当调用约定__stdcall而不是 __cdecl时,这对于许多 Windows DLL 来说很常见(它们通常编写 WINAPI 或 CALLBACK 而不是 __sstdcall),导出函数的名称通常以 @n 为后缀,其中 n 是参数堆栈上预期的字节数。 就您而言,它可能是. 指示喜欢并告诉编译器在编译时导入/链接 DLL 时自动处理此类事情。U2U_Test@0__declspec(dllimport)__declspec(dllexport)

在 C++ 中,使用复杂的名称修饰来支持方法、函数重载、模板和其他功能,每个编译器都发明了疯狂的命名方案,以确保永远不会有任何冲突。 因为在 DLL 级别,没有模板,没有类,只有按其名称或 ID 索引的导出符号列表。 这就是为什么大多数 DLL 都是用 C 语言导出的,也是为什么大多数头文件在块内声明来自 DLL 的函数的原因。extern "C" { ... }