4

我想以这种方式调用 MessageBox() 函数:

1)。加载所需的库
2)。获取函数地址
3). 称它为

因此,对于我理解的目标,我应该在 MessageBox 函数中定义具有所有类型参数的新类型。

它返回 INT 并接受:HWND、LPCSTR、LPCSTR、UNIT。

所以我注册了新类型:

typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);

我在调用此类函数时遇到问题。这种方式适用于所有功能还是仅适用于导出?
我怎样才能以这种方式准确地调用 MessageBox?

完整代码:

#include <iostream>
#include <windows.h>

using namespace std;

typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);

int main(void)
{
    HINSTANCE__ *hModule = LoadLibrary(L"\\Windows\\System32\\User32.dll");
    msgbox *me = 0;

    if(hModule != 0)
    {
        me = (msgbox*)GetProcAddress(hModule, "MessageBox");
    }

    return 0;
}
4

1 回答 1

5

您为什么将所有内容都声明为指针?

LoadLibrary返回 an HMODULE,而不是 an HINSTANCE__ *(它将与后者一起使用,但最好遵守文档)。

同样,msgboxis typedef'd 到函数指针类型,所以me是 a msgbox,而不是 a msgbox *

失败的原因GetProcAddress是因为 user32.dll 导出了 2 个函数,MessageBoxAMessageBoxW. 当您简单地调用MessageBox代码时,Windows.h 中定义的宏会将其替换为 2 个实际函数名称之一,具体取决于您是否正在编译UNICODE。但是,当您尝试直接访问导出的函数时,您需要明确指定要获取指向的指针。

#include <iostream>
#include <windows.h>

typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);

int main(void)
{
  HMODULE hModule = ::LoadLibrary(L"User32.dll");
  msgbox me = NULL;

  if( hModule != NULL ) {
    me = reinterpret_cast<msgbox>( ::GetProcAddress(hModule, "MessageBoxA") );
  }

  if( me != NULL ) {
    (*me)( NULL, "I'm a MessageBox", "Hello", MB_OK );
  }

  if( hModule != NULL ) {
    ::FreeLibrary( hModule );
  }
}
于 2012-04-12T17:31:28.397 回答