为什么GetProcAddress在实现时抛出异常?

时间:2018-01-21 13:14:27

标签: c++ winapi

这是我的头文件包含的内容:

extern HMODULE Ws_32;
extern HMODULE User32;
extern HMODULE Kernel32;
extern HMODULE Advapi32;

typedef int (WINAPI *fnMessageBox)(
    _In_opt_ HWND    hWnd,
    _In_opt_ LPCTSTR lpText,
    _In_opt_ LPCTSTR lpCaption,
    _In_     UINT    uType
);

struct API
{
    HMODULE User32;
    fnMessageBox _MessageBox;
};

这就是我的CPP文件所包含的内容:

API Api;

VOID Tools::LoadApis(API Api)
 {
    if ((Api.User32 = GetModuleHandleW(L"USER32.DLL")) == ERROR)
    {
        Api.User32 = LoadLibraryW(L"USER32.DLL");
    }

    if (Api.User32)
    {
        Api._MessageBox = fnMessageBox(GetProcAddress(Api.User32, "MessageBox"));
    }
}

int main()
{
    Tools::LoadApis(Api); // not a part of the example
    Api._MessageBox(0, 0, 0, 0);
}

在线,我打电话

Api._MessageBox(0, 0, 0, 0);

定义后

Api._MessageBox = fnMessageBox(GetProcAddress(Api.User32, "MessageBox"));

我收到内存异常,如下所示:

  

rat.exe中0x00000000处抛出异常:0xC0000005:访问冲突执行位置0x00000000。

1 个答案:

答案 0 :(得分:4)

Api._MessageBox永远不会抛出/ C ++ / exception。真正的问题是你永远不会检查存储在MessageBox中的返回值。

另请注意,WinAPI中的MessageBoxW是一个扩展为从user32导出的MessageBoxAGetProcAddress(Api.User32, "MessageBox")的宏。因此Api返回null是有意义的。

在第二个注释中,代码中存在错误:初始化Api函数参数,但随后使用API全局变量(仍未初始化)。你应该摆脱全局变量并通过引用传递VOID Tools::LoadApis(API & Api) { //... } int main() { API Api{}; Tools::LoadApis(Api); // not a part of the example if(Api._MessageBox) { Api._MessageBox(0, 0, 0, 0); } }

{{1}}