C++で作るDLLにはDEFファイルをつけるべき

DLLファイル関連でハマりました。C++で作ったDLLで、

_declspec(dllexport)

を使ってエクスポートした関数をC#側から読み込もうとしても、うまくいきません。「エントリ ポイントがありません」と言われて動きません。原因を調べたところ、dllexportの仕様で、名前に余計な文字列を付けるからだそうです。

例えば、SetDataという関数をDLLに

__declspec(dllexport) void SetData(unsigned char* data)

と登録したとします。Dependency Walkerを使ってDLLを開くと

?SetData@@YAXPAEH@Z

という意味の分からない名前に変化してしまいます!!

C++アプリケーション同士のインポート、エクスポートなら問題ありません。呼び出し側が_declspec(dllimport) を使ってインポートすれば、わけわかめな名前を自動的に解決してくれます。しかしVBやC#などの外部アプリケーションからC++のDLLを使うなら、もともとのメソッド名(SetData)が公開されていないため、エントリポイントがないよ、と文句を言われてしまうわけです。

そこで、DEFファイル(モジュール定義ファイル)が必須となります。外部アプリケーションに対して、これこれのメソッドを公開しますよ、ということを明示するファイルです。

LIBRARY    “TestLib”

EXPORTS
    SetData

内容はこれだけでOKです。VC++を使っているなら、新規作成する項目の中にDEFファイルが存在するはずですので、EXPORTS以下だけを設定すればよいです。

これで、再度Dependency WalkerでDLLの内容を覗くと、見事 SetData というメソッドが公開されていることがわかります。

外部へのメソッドの公開はCOMで行うという手もありますが、COMはオブジェクトを作成することが前提の仕組みですので、目的によって使い分ける必要がありますね。

 

参考

DLLコンパイル時の注意点

COM (Component Object Model)


コメントを残す

メールアドレスが公開されることはありません。