如何用GetProcAddress函数调用MessageBox?

4 function call dllimport getprocaddress dllexport

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

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

因此,为了我所理解的目标,我应该在 MessageBox 函数中使用所有类型的参数定义新类型。

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

所以我注册了新类型:

typedef int(__stdcall *msgbox)(HWND, LPCSTR, LPCSTR, UINT);
Run Code Online (Sandbox Code Playgroud)

我在调用此类函数时遇到问题。这种方式适用于所有功能还是仅适用于导出?
我怎样才能准确地以这种方式调用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;
}
Run Code Online (Sandbox Code Playgroud)

Pra*_*ian 5

为什么你要把所有东西都声明为指针?

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

同样,msgboxis typedef'd 为函数指针类型,mea 也是如此msgbox,而不是 a msgbox *

失败的原因GetProcAddress是因为user32.dll导出了2个函数,MessageBoxA并且MessageBoxW. 当您简单地调用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 );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @user1131997:始终遵循官方文档。如果 Visual Studio 的下一个版本使“HMODULE”不再是“HINSTANCE__*”怎么办? (3认同)
  • @user1131997我认为没有得到答复是有原因的,没有办法做到这一点:-) (2认同)