- ベストアンサー
DLLでメンバ関数をエクスポートする方法
VC++2005でDLLを作成しています。 そこで、クラスのメンバ関数をエクスポートする必要が出てきました。 クラスのメンバ関数を __declspec(dllexport) を使用せず、 DEFファイルを使用してエクスポートするには、 どのようにしたらよろしいでしょうか。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。 DLLプロジェクトにMAPファイルの作成を設定してから、ビルドします。 MAPファイル名を指定しない場合、MAPファイル名には、DLLプロジェクト名が使用されます。 作成されたMAPファイルをメモ帳で開いて、メンバ関数につけられた装飾名を確認してDEFファイルに記載します。 「MAPファイル作成の設定」 http://msdn.microsoft.com/ja-jp/library/k7xkk3e2(v=vs.80).aspx 「DEFファイルを使用したクラスのエクスポート」 http://hata.cc/docs/DLL/4.html 当方のVisualStudio2008で、以下のクラスをエクスポートして、成功しています。 class CTest { public: CTest(); CTest(const CTest& r); ~CTest(); CTest& operator = (const CTest& r); void Fun(); int Fun(int i); private: }; DEFの中身 LIBRARY "class" EXPORTS ??0CTest@@QAE@XZ @1 ??0CTest@@QAE@ABV0@@Z @2 ??1CTest@@QAE@XZ @3 ??4CTest@@QAEAAV0@ABV0@@Z @4 ?Fun@CTest@@QAEXXZ @5 ?Fun@CTest@@QAEHH@Z @6
その他の回答 (3)
- aris-wiz
- ベストアンサー率38% (96/252)
>繰り返しになりますが、 >求めているのは __declspec(dllexport) を使用するのではなく、 >DEFファイルを使用してエクスポートする方法です 本文を読まれた上での補足でしょうか? 先の回答での方法は、__declspec(dllexport) を 使用していませんが。。。? なぜ、DEFファイルにそこまでこだわるのかよく分かりませんが DEFファイルを用いても、__declspec(dllexport)を 用いた場合との動作差分はほとんど無いということを理解されていますか? ほとんどというのは、DLLを作成した環境と同じ環境で DLLの呼び出し側もビルドする必要があります。 これは、DEFファイルに記述した修飾名を コンパイラが生成するものと合わせる為です。 つまり、外部にDLLを公開する場合は、 コンパイル環境に合わせられるようにしておかなくては 使用できませんので注意してください。 基本的に、DEFファイルを使用しなければならない、 という状況はDLLエクスポートの序数を制御しなければならない 時くらいだと思うのですが。。。? なお、繰り返しになりますが __declspec(dllexport) とDEFファイルでの Exportは2者択一です
お礼
えーと、この回答の意図はわかりかねますが、 もし、通常の回答として投稿したのであれば、 もう一度最初から勉強をしなおすか、もっと開発の経験を積むことをお勧めします。 もし、故意にこのような間違いだらけの回答をしたのであれば、 それは非常に悪質な行為であり、直ちにやめるべきです。 いずれにしろ、質問に対する回答になってない上に、 間違いだらけの回答のため、無視します。
- aris-wiz
- ベストアンサー率38% (96/252)
>クラスのメンバ関数を __declspec(dllexport) を使用せず、 普通、クラスに上記をつければ、 すべてのメソッドがExportされるはずですが。。。 クラス内の各メソッドをDEFファイルに書くには、 コンパイル時に自動的に割り当てられる修飾子を すべて書く事でExport出来るようです。 ただし、クラスに __declspec(dllexport) を 使用している場合、2重Exportだと怒られますし、 この方法はMSで推奨もされていませんし、 わたしのローカルでの確認結果なのであしからず。 ちなみに、クラスの__declspec(dllexport)を 外すと、すべてのメソッドについて、DEFファイルを 記述しなければなりません。(コンストラクタもです) class CClassExport { public: CClassExport(void); // TODO: メソッドをここに追加してください。 virtual bool AAA(int); }; LIBRARY "ClassExport" EXPORTS ??0CClassExport@@QAE@XZ @1 ?AAA@CClassExport@@UAE_NH@Z @2 virtualにしているのは、実装せずコンパイルエラーにして、 修飾されたメソッド名を知る為にvirtualにしているので 修飾名が分かれば別に必要ありません。 まぁ、出来ない事はないのですが、 はっきり言って本当にDEFファイルが必要なのか もう一度見直した方が良いように思われます。 ちなみに、コンパイルする毎にメソッドの修飾子は変わるので、 その都度、libファイルを更新しなければ、結局Exe側から DLL内に含まれているメソッドを呼び出す事が出来ません。 スタティックリンクライブラリを使用する方がよっぽどマシです。 #というより、DLLにしても変わりがない。
お礼
この回答について、 回答者のレベルが疑わしいため、無視します。
補足
> >クラスのメンバ関数を __declspec(dllexport) を使用せず、 > 普通、クラスに上記をつければ、 > すべてのメソッドがExportされるはずですが。。。 繰り返しになりますが、 求めているのは __declspec(dllexport) を使用するのではなく、 DEFファイルを使用してエクスポートする方法です。
- Sweet_potato
- ベストアンサー率66% (6/9)
普通の関数をエクスポートするときは LIBRARY SECTIONS .sharedata READ WRITE SHARED EXPORTS myfuncA @1 myfuncB @2 見たいな感じで.defファイルを書き 使えばいいんですが クラスのメンバ関数となると(推測ですが)静的メンバ関数でない限り無理だと思います メンバ関数は裏で自分自身のクラスのアドレスを引数で取っているので アドレスを使って呼び出すことができないからです それでもやりたいならクラス本体をヘッダーに書いて、 関数はdllにある(メンバ関数ではない)のを 使うデータを引数にして呼び出せば似たような動作ができるはずです 自分の場合はそれで解決しました
お礼
静的なメンバ関数をDEFファイルでエクスポートすることができました。 回答いただき、ありがとうございます。
補足
> クラスのメンバ関数となると(推測ですが)静的メンバ関数でない限り無理だと思います それでは、静的メンバ関数をDEFファイルでエクスポートするにはどうしたらいいでしょうか。
お礼
具体的なソースコードと参考URLが非常に参考になりました。 問題は解決しました。 ありがとうございます。