dポイントプレゼントキャンペーン実施中!

VC++2005でDLLを作成しています。
そこで、クラスのメンバ関数をエクスポートする必要が出てきました。

クラスのメンバ関数を __declspec(dllexport) を使用せず、
DEFファイルを使用してエクスポートするには、
どのようにしたらよろしいでしょうか。

A 回答 (4件)

 こんにちは。



 DLLプロジェクトにMAPファイルの作成を設定してから、ビルドします。
 MAPファイル名を指定しない場合、MAPファイル名には、DLLプロジェクト名が使用されます。
 作成されたMAPファイルをメモ帳で開いて、メンバ関数につけられた装飾名を確認してDEFファイルに記載します。

 「MAPファイル作成の設定」
 http://msdn.microsoft.com/ja-jp/library/k7xkk3e2 …

 「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
    • good
    • 0
この回答へのお礼

具体的なソースコードと参考URLが非常に参考になりました。

問題は解決しました。
ありがとうございます。

お礼日時:2011/03/24 21:04

>繰り返しになりますが、


>求めているのは __declspec(dllexport) を使用するのではなく、
>DEFファイルを使用してエクスポートする方法です
本文を読まれた上での補足でしょうか?
先の回答での方法は、__declspec(dllexport) を
使用していませんが。。。?


なぜ、DEFファイルにそこまでこだわるのかよく分かりませんが
DEFファイルを用いても、__declspec(dllexport)を
用いた場合との動作差分はほとんど無いということを理解されていますか?


ほとんどというのは、DLLを作成した環境と同じ環境で
DLLの呼び出し側もビルドする必要があります。
これは、DEFファイルに記述した修飾名を
コンパイラが生成するものと合わせる為です。


つまり、外部にDLLを公開する場合は、
コンパイル環境に合わせられるようにしておかなくては
使用できませんので注意してください。


基本的に、DEFファイルを使用しなければならない、
という状況はDLLエクスポートの序数を制御しなければならない
時くらいだと思うのですが。。。?


なお、繰り返しになりますが
__declspec(dllexport) とDEFファイルでの
Exportは2者択一です
    • good
    • 0
この回答へのお礼

えーと、この回答の意図はわかりかねますが、


もし、通常の回答として投稿したのであれば、
もう一度最初から勉強をしなおすか、もっと開発の経験を積むことをお勧めします。

もし、故意にこのような間違いだらけの回答をしたのであれば、
それは非常に悪質な行為であり、直ちにやめるべきです。


いずれにしろ、質問に対する回答になってない上に、
間違いだらけの回答のため、無視します。

お礼日時:2011/03/24 21:03

>クラスのメンバ関数を __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ファイルを使用してエクスポートする方法です。

補足日時:2011/03/23 21:48
    • good
    • 0
この回答へのお礼

この回答について、
回答者のレベルが疑わしいため、無視します。

お礼日時:2011/03/24 21:05

普通の関数をエクスポートするときは



LIBRARY
SECTIONS
.sharedata READ WRITE SHARED
EXPORTS
myfuncA @1
myfuncB @2

見たいな感じで.defファイルを書き
使えばいいんですが
クラスのメンバ関数となると(推測ですが)静的メンバ関数でない限り無理だと思います
メンバ関数は裏で自分自身のクラスのアドレスを引数で取っているので
アドレスを使って呼び出すことができないからです

それでもやりたいならクラス本体をヘッダーに書いて、
関数はdllにある(メンバ関数ではない)のを
使うデータを引数にして呼び出せば似たような動作ができるはずです
自分の場合はそれで解決しました

この回答への補足

> クラスのメンバ関数となると(推測ですが)静的メンバ関数でない限り無理だと思います

それでは、静的メンバ関数をDEFファイルでエクスポートするにはどうしたらいいでしょうか。

補足日時:2011/03/22 21:24
    • good
    • 0
この回答へのお礼

静的なメンバ関数をDEFファイルでエクスポートすることができました。

回答いただき、ありがとうございます。

お礼日時:2011/03/24 21:06

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!