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

すべてをポインタとして宣言するのはなぜですか?

LoadLibraryHMODULEではなく を返しますHINSTANCE__ *(後者でも動作しますが、常にドキュメントに従うことをお勧めします)。

同様に、msgboxis はtypedef関数ポインター型に変換されるのでme、 amsgboxではなく amsgbox *です。

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 );
  }
}
于 2012-04-12T17:31:28.397 に答える