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はオブジェクトを作成することが前提の仕組みですので、目的によって使い分ける必要がありますね。
参考