読者です 読者をやめる 読者になる 読者になる

DLLまとめ 03 defファイル

DLLの簡単なまとめです。
defファイルについて


__stdcall指定された関数の名前

MSDNこちらのページに

__stdcall 方式で装飾された名前には、シンボル名の前に _ (アンダースコア)、シンボルの後に @ (アット マーク) が付けられ、その後に引数リストのバイト数 (必要なスタック空間) が付けられます。

という記述があります。
なので、まとめ01で作成したmyDLLに含まれるtest()関数は、_test@0という名前になります。
これは、dumpbinで確認できます。
Visual Studio開発者コマンドプロンプトに、

dumpbin myDLL.dll -exports

と入力することで確認できます。
dumpbinの結果は次の画像になりました。
f:id:skru_y:20140318151425j:plain
この規則は、DLLを明示的に読み込むときやVisualStudio以外のツールからDLLを利用するときに問題を起こします。


defファイルを使う

defファイルを使えば、DLLが公開する関数の名前を指定できます。
まず、テキストエディタ拡張子がdefとなっているファイルを作成します。
次に、DLLを作成するプロジェクトのモジュール定義ファイルに、defファイルを追加します。
f:id:skru_y:20140318151126j:plain
defファイルに次のコードを記述し、ビルドします。

EXPORTS
 test


defファイルを適用しビルドされたDLLをdumpbinで調べると、関数名がtestになっていることがわかります。
f:id:skru_y:20140318151517j:plain
defファイルが適用されたlibファイルは、関数名が_test@0のままです。
f:id:skru_y:20140318153639j:plain


ここで、暗黙的なDLL呼び出し時、リンカが_test@0という名前の関数を呼び出そうとしてエラーになるように見えますが、エラーは起こらず、_test@0とDLLのtestが対応付けられます。
なので、defファイルにより暗黙的なDLL呼び出しが失敗することはありません。