Extern CおよびDllexport vsモジュール定義を使用したstdcall名マングリング(MSVC ++)

StackOverflow https://stackoverflow.com/questions/4550294

質問

DLLの簡単なテスト関数をエクスポートして、呼び出し条約を次のように指定するアプリケーション(FYI:MIRC)で動作しようとしていました。

int __stdcall test_func(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)

さて、アプリケーションからこれを呼び出すために、私は使用しています test_func しかし、私は名前がマングリングのために、私が思っていたほど単純ではないことに気づきました。

ここの同様のトピックを通して、私は使用することを理解することになりました extern "c" と組み合わせて __declspec(dllexport) モジュール定義からマングリングを削除する(.def)を削除する(多少)等しい(やや)方法です。ただし、extern/dllexportメソッドを使用する場合、私の関数(例として)は常にです _test_func@numbers 一方、.defは、エクスポートに必要なアプリケーションでの使用に必要なすべてのマングルを削除しました。

なぜこれがなぜあるのかを誰かが説明してもらえますか?私は2つの方法に興味があります。ありがとう!

役に立ちましたか?

解決

dllexport/Importは、GetProcAddressを使用した古いCライブラリではなく、それ自体でロードされるように設計されています。あなたが見たマングリングは、すべてのMicrosoftコンパイラが__STDCALL関数のために長い間行ってきたことです。ほとんどの場合、ターゲットは__stdcallではなく__cdecl関数を期待していますが、そうでない場合は、.defファイルを使用して名前を特別に解除する必要があります。

他のヒント

extern "C" stdcallとは何の関係もありません。それは、C ++名のマングリング(別名タイプセーフリンケージ、シンボル名にタイプ情報を含める)が無効になることを宣言します。 C呼び出し条約またはSTDCall Calling Conventionを使用するかどうかに関係なく、使用する必要があります。

Stdcall Calling Conventionでは、Calleeはスタックからパラメーターを削除します。それを安全にするために、エクスポートされた名前には、カリーがスタックから削除するバイト数が含まれています。

あなたがエクスポートしているアプリケーションが必要なことを要求する場合 @number 接尾辞は名前に追加されますが、おそらくC通話慣習が予想されることを意味します。したがって、関数の宣言を停止する必要があります __stdcall. 。あなたがそれを宣言するとき declspec(dllexport), 、DLLで装飾されていない名前を取得する必要があります。

DEFファイルでは、必要なものを何でも呼び出すことができます。追加のチェックは実行されません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top