使用する関数を指定する .def ファイルを作成して、アンマネージ DLL から C プロジェクトに関数をインポートしようとしています。MessageBoxA
からWinAPI 関数の練習をしていますuser32.dll
。これは、他の WinAPI 関数と同様に stdcall 関数です。.def ファイルを作成する方法は次のとおりです。
LIBRARY user32.dll
EXPORTS
_MessageBoxA@16
次に、次のように .lib を作成しlib /def:"C:\Path\to\def\user32.def" /
out:"C:\path\to\project\user32-mb.lib"
ます。次に、私の C プロジェクトでは、次のことを行います。user32-mb.lib
user32-mb.exp
#pragma comment(lib, "user32-mb.lib")
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
EXTERNC __declspec(dllexport) int __stdcall MessageBoxA(void *hWnd, char *lpText, char *lpCaption, int uType);
void main(){
MessageBoxA(0, "MessageBox test", "MessageBox test", 0x00000030L);
}
ただし、リンクすると、次のエラーが発生します。
error LNK2019: unresolved external symbol _MessageBoxA@16 referenced in function _main
ただし、.def の宣言を次のように変更すると:
LIBRARY user32.dll
EXPORTS
MessageBoxA
そして、Cコードの関数プロトタイプを次cdecl
の代わりに変更しstdcall
ます。
EXTERNC __declspec(dllexport) int __cdecl MessageBoxA(void *hWnd, char *lpText, char *lpCaption, int uType);
メッセージ ボックスは実際に表示されますが、閉じるとすぐにエラーがスローされます。
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
cdecl
これは、結局必要なので、
で呼び出すことも悪い考えであることを示していますstdcall
。
stdcall
問題は、両方のエラーを回避し、関数を適切にインポートして呼び出すために、.def ファイルまたはプロジェクトで何を変更する必要があるかということです。