トップ回答者
MFC/DLLのクラス・メソッドのインポート・エクスポート

質問
-
OS:WindowsXP Professional SP3
環境:VisualStudio2005
言語:C++(MFC)
VisualStudio2005を使用し、MFCのDLLを作成しようと試みている初心者です。
MFCのネットワークのライブラリを使用するためにMFCでDLLを作成しています。
DLLの用途として、
MFCの他、
VB・C++にも使用できるようにしたいと思っています。
しかし、インポート/エクスポートがわかりません。
DLL内にあるクラスもしくはメソッドをエクスポートしたいのです。
色々なHPを見て作成手順を調べ、実際に作成しました。
下に実際に作成した手順を記述します。
ご指摘お願いします。MFC/DLL作成
1.[ファイル]→[新規作成]→[プロジェクト]→[MFCDLL]
[共有MFCDLLを使用する通常のDLL]を作成(windowsソケットにチェック)
2.DLL作成
[既存の項目]から自作クラスを追加
自作クラスの詳細を下に記します。
////////////////////////////////////////////////////////////////////////////////
//sample.h////////////////////////////////////////////////////////////////////////////////
#include "jisaku.h" //自作クラス
class sample{
public:
//メンバ
Jisaku* jisaku; //自作クラス
//メソッド
__declspec(dllexport) void function(void);
}
////////////////////////////////////////////////////////////////////////////////
//sample.cpp////////////////////////////////////////////////////////////////////////////////
__declspec(dllexport) void sample::function(void)
{jisaku = new Jisaku(); //自作クラスインスタンス生成
AfxMessageBox(_T("test"));
}
3.EXEの作成
[ファイル]→[新規作成]→[プロジェクト]→[MFCアプリケーション]
[ダイアログベース]を作成。
[クラスビュー]から[MFCクラス]を追加。(クラス名ample_exe・基本クラス:CDialog)
追加したクラスのヘッダ部にインポートを記述。
__declspec(dllimport) void function(void);
//ボタンのクリックイベントvoid (ダイアログ名):
nBnClickedButton()
{
function(); //※1
}
4..dll/.libの設定。
[プロジェクト]→[プロパティ]→[リンカ]→[入力]に項2で作成したlibのパスを入力。
DLLをDebug下に.dllを配置する。
5.実行
コンパイルエラーとなり、実行できず。
ご指摘お願いいたします。
宜しくお願いいたします。
[余談]
色々試しました。
一度だけ実行できた方法が、グローバルな関数を.defファイルに記述する方法です。
しかし.defファイルに記述する方法もクラス、メソッドのインポート/エクスポートはうまくいきませんでした。
回答
-
あぱる さんからの引用 しかし、インポート/エクスポートがわかりません。
DLL内にあるクラスもしくはメソッドをエクスポートしたいのです。クラスをエクスポートするのであれば、クラス自体に修飾が必要です。
http://msdn.microsoft.com/ja-jp/library/z4zxe9k8.aspx
http://msdn.microsoft.com/ja-jp/library/a90k134d.aspx
クラスのメソッド単位でできるかどうかは未確認ですが、少なくとも非staticのインスタンスメソッドは通常エクスポートできません。
(誰がインスタンスを作るのかという問題にもなる)
あぱる さんからの引用 MFCのネットワークのライブラリを使用するためにMFCでDLLを作成しています。
DLLの用途として、
MFCの他、
VB・C++にも使用できるようにしたいと思っています。
VBでも使えるようにするのであれば、クラスレベルではなく、関数レベルでエクスポートして下さい。
この際、クラスのメンバ関数ではなく、グローバルの関数が分かりやすいかもしれません。
どうしてもクラス単位でVBから使いたいというのであれば、VB2005に対してはC++/CLIでラップしてあげるとか手法はあります。
条件が分からないので、今回は割愛します。
すべての返信
-
あぱる さんからの引用 しかし、インポート/エクスポートがわかりません。
DLL内にあるクラスもしくはメソッドをエクスポートしたいのです。クラスをエクスポートするのであれば、クラス自体に修飾が必要です。
http://msdn.microsoft.com/ja-jp/library/z4zxe9k8.aspx
http://msdn.microsoft.com/ja-jp/library/a90k134d.aspx
クラスのメソッド単位でできるかどうかは未確認ですが、少なくとも非staticのインスタンスメソッドは通常エクスポートできません。
(誰がインスタンスを作るのかという問題にもなる)
あぱる さんからの引用 MFCのネットワークのライブラリを使用するためにMFCでDLLを作成しています。
DLLの用途として、
MFCの他、
VB・C++にも使用できるようにしたいと思っています。
VBでも使えるようにするのであれば、クラスレベルではなく、関数レベルでエクスポートして下さい。
この際、クラスのメンバ関数ではなく、グローバルの関数が分かりやすいかもしれません。
どうしてもクラス単位でVBから使いたいというのであれば、VB2005に対してはC++/CLIでラップしてあげるとか手法はあります。
条件が分からないので、今回は割愛します。
-
返信遅くなり申し訳ございません。
Azulenさん返信ありがとうございます。>クラスをエクスポートするのであれば、クラス自体に修飾が必要です。
>http://msdn.microsoft.com/ja-jp/library/z4zxe9k8.aspx
>http://msdn.microsoft.com/ja-jp/library/a90k134d.aspx
> クラスのメソッド単位でできるかどうかは未確認ですが、少なくとも非staticのインスタンスメソッドは通常エクスポートできません。
> (誰がインスタンスを作るのかという問題にもなる)
参考ページありがとうございます。
只、このページを参考に作成したものが先頭スレで記述させていただいたソースなんです。>クラスのメソッド単位でできるかどうかは未確認ですが、少なくとも非staticのインスタンスメソッドは通常エクスポートできません。
>(誰がインスタンスを作るのかという問題にもなる)
単に修飾子をつけるだけではよくないのでしょうか?
static宣言を明示しなければいけないのですか?
質問ばかりですいません。
//エクスポート
class A{
public:__declspec(dllexport) static void function(); //staticなしではエクスポートできない??
}
このような記述でよろしいのでしょうか?>VBでも使えるようにするのであれば、クラスレベルではなく、関数レベルでエクスポートして下さい。
>この際、クラスのメンバ関数ではなく、グローバルの関数が分かりやすいかもしれません。
グローバルの関数で試みます。 -
どーも、PATIOといいます。
横槍になってしまいますが。
あぱる さんからの引用 >クラスのメソッド単位でできるかどうかは未確認ですが、少なくとも非staticのインスタンスメソッドは通常エクスポートできません。
>(誰がインスタンスを作るのかという問題にもなる)
単に修飾子をつけるだけではよくないのでしょうか?
static宣言を明示しなければいけないのですか?
質問ばかりですいません。
//エクスポート
class A{
public:__declspec(dllexport) static void function(); //staticなしではエクスポートできない??
}
このような記述でよろしいのでしょうか?staticが付いたクラスのメンバー関数がどういうものであるのかと言う事を理解されているでしょうか?
エクスポートでstatic(静的)でないクラスのメンバー関数だけをエクスポートしたとしても
staticでないメンバー関数を呼び出す為にはそのクラスのインスタンスが必要になりますよね。
ところが、クラス自体がエクスポートされていないとクラスのインスタンスを作成する事が出来ません。
インスタンスが作成できないと静的でないメンバー関数は呼び出せませんから意味がありません。
あと、staticなメンバー関数はクラスのインスタンスが無くても呼び出せる代わりに制限があります。
逆を言うとこの制限があるからクラスのインスタンスが無くても呼び出せるわけなんですが、
その部分をちゃんと理解した方が良いと思います。
C++の文法に関して怪しい部分があるのであれば、文法書とか入門書を読み返すようにした方が良いと思います。
一通り通して勉強していても完全には身についていないと思うので反復する事が必要だと思います。
ちなみにstaticで宣言出来ないメンバー関数をエクスポートするのであれば、当然クラス自体をエクスポートしないと
駄目です。どうしても特定の関数だけをエクスポートしたいのであれば、適切なインスタンスを作成してメンバー関数を
呼び出し、その結果を返してくれるようなグローバル関数を作成する事が必要になると思います。
-
PATIOさん返答ありがとうございます。
>staticが付いたクラスのメンバー関数がどういうものであるのかと言う事を理解されているでしょうか?
>エクスポートでstatic(静的)でないクラスのメンバー関数だけをエクスポートしたとしても
>staticでないメンバー関数を呼び出す為にはそのクラスのインスタンスが必要になりますよね。
>ところが、クラス自体がエクスポートされていないとクラスのインスタンスを作成する事が出来ません。
>インスタンスが作成できないと静的でないメンバー関数は呼び出せませんから意味がありません。
>あと、staticなメンバー関数はクラスのインスタンスが無くても呼び出せる代わりに制限があります。
>逆を言うとこの制限があるからクラスのインスタンスが無くても呼び出せるわけなんですが、
>その部分をちゃんと理解した方が良いと思います。
クラスのインスタンスが無く、staticでないメンバー関数を呼び出しができる?
と疑問に思ってました。
理解が深まりました、ありがとうございます。
>C++の文法に関して怪しい部分があるのであれば、文法書とか入門書を読み返すようにした方が良いと思います。>一通り通して勉強していても完全には身についていないと思うので反復する事が必要だと思います。
おっしゃる通りです。
もう一度文法書を読み返し、基礎を固めたいと思います。
基礎を理解し、再度DLL化を試みます。
このスレを閉めさせていただきます。
本当にありがとうございました。