0

使用する関数を指定する .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.libuser32-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 ファイルまたはプロジェクトで何を変更する必要があるかということです。

4

4 に答える 4

1

dllimportではなくを使用する必要がありますdllexportが、この場合は を__declspec(...)完全に削除する必要があります。

そして、関数の正しい名前を指定する必要がありますMessageBoxA.

LIBRARY USER32.dll
EXPORTS
  MessageBoxA

また、正しいメイン宣言が

int main(void)
于 2014-08-15T06:52:41.440 に答える
-1

このページはwinuser.hがヘッダーであることを示しています。そこから、 や など、いくつかのマクロが使用されていることがわかりWINUSERAPIますWINAPIWINUSERAPIそのヘッダーの先頭に条件付き#defineで -d があります。 プラットフォームに応じて、呼び出し規約に結び付けられていることWINAPIがわかります。winbase.h

しかし、より良い質問は次のとおりです。なぜ を使用し、使用dllexportしないのdllimportですか?

于 2014-08-14T20:44:10.530 に答える