5

首先是的,我已经搜索了一段时间,但找不到与我的案例相关的任何答案。基本上,我试图在 Windows DLL (dnsapi.dll) 中获取函数的地址,而 GetProcAddress 返回 0。经过一段时间的挠头后,我什至继续创建一个程序,该程序仅在 user32 中使用 MessageBox 的 GetProcAddress。 dll。结果相同。这是我制作的第二个程序的代码,但仍然无法正常工作:

#include <stdio.h>
#include <Windows.h>

int main() {
    HINSTANCE hLib = LoadLibrary(TEXT("user32.dll"));
    DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBox");

    printf("%ld", MsgBoxAddr);
    getchar();

    return 0;
}

顺便说一句,GetLastError 返回 127,这似乎是 GetProcAddress 不起作用时返回的最常见错误,但我不知道出了什么问题,我尝试了许多函数和 DLL,而不仅仅是这对。

谢谢。:)

编辑:链接的文章解决了我的问题,我尝试的功能都有unicode和anis版本(w和a)。使用完整的 API 名称解决了这些问题。感谢您链接该问题。

谢谢你。

4

2 回答 2

5

一些常见的 API 并不是函数的真实名称,包括LoadLibraryMessageBox。所有这些功能都不存在!

这是因为大多数将文本作为参数的 Windows API 都有两个版本,一个接受 ANSI 文本,另一个接受 UNICODE 文本。您知道的那些“函数”实际上是预处理器宏,它们会根据您的 Visual Studio 项目的默认字符集自动将您路由到正确的函数。

MessageBox例如,不存在。现有的是函数MessageBoxAMessageBoxW,一个用于 ANSI,另一个用于 UNICODE。因此,您将通过以下方式获得他们的地址:

ANSI:

HINSTANCE hLib = LoadLibraryA("user32.dll");
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBoxA");

统一码:

HINSTANCE hLib = LoadLibraryW(L"user32.dll");
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBoxW");

自动的:

HINSTANCE hLib = LoadLibrary(TEXT("user32.dll"));
#ifdef UNICODE
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBoxW");
#else
DWORD MsgBoxAddr = (DWORD)GetProcAddress(hLib, "MessageBoxA");
#endif
于 2013-11-23T04:43:42.257 回答
2

Havenard 已经给出了答案,所以不要接受我的答案(但一定要阅读)。

解决它的更好方法是定义:

#ifndef _CRT_STRINGIZE  // Might be already defined in crtdefs.h, but if not...
#define __CRT_STRINGIZE(Value) #Value
#define _CRT_STRINGIZE(Value) __CRT_STRINGIZE(Value)
#endif

然后使用

GetProcAddress(hLib, TEXT(_CRT_STRINGIZE(MessageBox)));
于 2013-11-23T04:50:46.020 回答