クラスの実体を一つにする方法

このQ&Aのポイント
  • クラスの実体を一つにする方法とは?
  • クラスAを含むDLLの実体を一つにする方法について紹介します。
  • シングルトンパターンを使用してクラスAの実体を一つにする方法について解説します。
回答を見る
  • ベストアンサー

クラスの実体を一つにする方法

現在、以下の構成でアプリケーションを開発しています。 フォーム(C#)⇔ラップDLL(C++/CLI)⇔処理(C++ネイティブのDLL多数) C++DLLのひとつにクラスAがあるとします。 このクラスAを含むDLLは他のDLLにリンクされています。 このクラスAの実体がアプリケーションの中で一つしかないようにするにはどのようにコーディングすれば良いのでしょうか? シングルトンパターンについて書かれたHPを参考につくってみたのですが、アプリケーションを実行するといくつも実体が作られています。 class __declspec(dllexport) DataStore { private: DataStore(): // コンストラクタ {}; ~DataStore() {}; // デストラクタ public: // このインスタンスを使用してメンバにアクセスする。 static DataStore& GetInstance() { static DataStore myInstance; return myInstance; } };

質問者が選んだベストアンサー

  • ベストアンサー
  • hitomura
  • ベストアンサー率48% (325/664)
回答No.1

2つ確認したいことがあります。 ・ひょっとして、GetInstance()メソッドの(宣言ではなく)定義をヘッダーファイルに書いていませんか? ・もし上記のようになっているならば、GetInstance()メソッドの定義をソースファイルに移してみたらどうなりますか?

mistmoon79
質問者

お礼

回答ありがとうございます。 はい、質問のソースコードはヘッダファイルに書いています。 GetInstance()メソッドをcppに持って行くと正常に動作しました! ヘッダに直接書いていた場合にダメなのはどうしてでしょうか? inline展開されてmyInstanceが別実体になってしまったのでしょうか?

関連するQ&A

  • VC++6.0で作成したDLLのクラスをVB6.0でインポートするには?

    VC++6.0で作成したDLLのクラスをVB6.0でインポートするにはどうしたらいいのでしょうか? 通常の関数なら__declspec(dllexport) __stdcall を書き,defファイルにEXPORT指定することで解決できたのですが,クラスごとエクスポートする場合にはVC側,VB側の記述をどのようにすれば良いのでしょうか?

  • 複数のクラスから利用する環境設定情報について

    やや抽象的な話になりますが、JavaのGUIアプリケーションの終了時に、 ・現在のウィンドウの座標 ・現在のウィンドウのサイズ ・最後に読み込んだファイル ・常に最前面に表示するか などのコンフィグを保存して、次回実行時にそれを読み込んで 複数のクラスから利用する場合どのような設計にするのが一般的なのかを知りたいです。 static クラスを作り、すべてのクラスからアクセスするようにする方法、 シングルトンクラスを設計して getInstance() で取得する方法、 通常のクラスで設定情報クラスを作り、他のクラスにコンストラクタの引数の形でインスタンスを渡す方法、 設定情報用の専用クラスを作らず、メインフォームのプロパティに読み込んだ後で、 他のクラスにメインフォームのインスタンスを渡す方法 規模やプログラムの種類によるかもしれませんが、どのやり方を使えばいいのでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • DLLでメンバ関数をエクスポートする方法

    VC++2005でDLLを作成しています。 そこで、クラスのメンバ関数をエクスポートする必要が出てきました。 クラスのメンバ関数を __declspec(dllexport) を使用せず、 DEFファイルを使用してエクスポートするには、 どのようにしたらよろしいでしょうか。

  • C#、C++間のDLLの呼び出しについて

    いつも拝見させていただいております。 さっそくですが、質問致します。 現在、ネイティブなC++ DLLを作成しています。 これを今回、C#のアプリケーションから呼び出すことになりました。 DLL内にはクラスを作成しており、内部にXMLのデータを保持するような クラスを作成しております。(XML操作にはMSXMLを使用しております。) 問題なのはC++アプリケーションから呼び出した時は正常に動作するのですが、C#からの呼び出しの時はC++アプリケーションから呼び出した時には発生していないエラーが検出されます。 エラー内容は System.AccessViolationException 保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。 になります。 エラー内容からしてC++内でのメモリ操作に問題があると 思われるのですが、C++からの実行時には検出されていないので理由がわからずに困っております。 ネイティブなDLLに対してはデバッグも行えないため、手に負えません。 (現在、1行ごとにログを埋め込み、TCHAR型のnewを4byte行っている箇所で処理がストップしてしまっているようです。C++からの呼び出し時には正常に処理される箇所です。) ネイティブなDLLに対してのデバッグ方法や似たような現象にあわれた方がいらっしゃいましたらご助力お願い致します。 ・対象のDLLのクラスは_declspec(dllexport)にてエクスポートを行っています。 ・C#からの呼び出し時にはネイティブなDLLのためC++/CLIで作成したプロジェクトでラッパークラスを作成してアクセスを行っています。 ・C++アプリケーションからの呼び出し時はプロパティの設定でインクルードディレクトリ、LIBファイルの設定等を行って直接DLLを参照して 実行(呼び出し)しています。

  • C#で実行可能なdllの作成方法

    現在、C#でアプリケーションを作成していますが、exe形式ではなくdll形式で実行可能な モジュールを作成したいです。 しかし、単に[STAThread]のMain関数を作ったり、staticコンストラクタを作成しただけでは 起動できません。 どうしたら実行可能なdllを作成できるのでしょうか。 最終的にやりたいことは、C++のCreateRemoteThread()からこのdllを起動することです。 どうぞよろしくお願いします。

  • EXE1→DLL→EXE2数値を受け渡す方法

    C++プログラムの初級者です。 EXE1の数値をDLLの関数Func1に渡し、そこで計算した結果を関数Func2でEXE2に送るプログラムを作成しています。 下記のようなDLLのコードを作成したのですが、うまく数値を受け渡すことが出来ません。 調べてみると、EXE1⇔DLLとEXE2⇔DLLとは、アドレス空間が別なので、DLLのStatic変数を共有できないようです。 EXE1⇔DLL と EXE2⇔DLL の1対1では数値受け渡しは、正常に動作しています。 具体的に、DLLにどのようなコードを書けば、数値を受け渡すことができるのでしょうか? ご指導よろしくお願いします。 VC++2010ExpressEdition で作成しています。 <DLLのソースコード> ---------------------- #define WIN32_LEAN_AND_MEAN #include <windows.h> #include <stdlib.h> #include <stdio.h> #include <iostream> static double aa, bb; __declspec(dllexport) double __stdcall Func1(double a1, double b1) { aa = a1*2; return (double)(aa); } __declspec(dllexport) double __stdcall Func2(double a2, double b2) { return (double)(aa); } BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { //---- switch(ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } //---- return(TRUE); }

  • C++のテンプレート関数やテンプレートクラスをC#で利用するには?

    C++で作成したテンプレート関数やテンプレートクラス をC#で利用したいと考えております。 テンプレート関数やクラスを明示的実体化してコンパイルし、 C++/CLIでラップすればC#でも使えるという話を聞きました。 テンプレートでない通常の関数やクラスの場合は、 http://www.atmarkit.co.jp/fdotnet/special/vcppinvista01/vcppinvista01_01.html で紹介されているのを見つけたのですが、 テンプレート関数やクラスの場合 具体的にC++/CLI側でどのように記述すればよいか分かりません。 例えば、 ---- [test.h] template <class Type1> class Test{ public:   Type1 x;   template <class Type2>   Type1 func(Type2 y){ ... } }; ----- のようなクラスがあった場合、どうすればよいでしょうか。 明示的な実体化の方法とC++/CLIで明示的実体化した関数やクラスが どのような名前になるのかが分かれば上記サイトの方法で いけるのではないかと思っているのですが…。 環境はVisual Studio2005(or 2008)です。 よろしくお願いいたします。

  • C++ シングルトン マルチスレッド

    標準C++でシングルトンを実装したいのですが。 class Singleton{ public: static Singleton* getInstance(){ if (_instance == NULL){ //スレッドAがこの時点で、スレッドBがNULLチェックすると破綻する _instance = new Singleton(); } return _instance; } private: Singleton(); static Singleton* _instance; }; マルチスレッドになると上記のパターンで破綻するといわれどうしたものかと考えております。 static Singleton* _instance = new Singleton(); と出来れば解決なのですが 「static const int データメンバ以外をクラス内で初期化することはできません」 とのことでそれもできず。 どのようにすればよいでしょうか。

  • クラス内にnewで形成した配列等が含まれる場合

    クラスを関数内に作成した時にそれを実体コピーさせるreturnで返したいんですが、class内newで形成した動的配列があるため、返した後デストラクタが呼ばれるので動的配列の中身が消滅してしまう(させている)のですが、動的配列の消去にデストラクタを使用しないようにするしかありませんか? class a{ public: int *b; a(){b=new int[10];} ~a(){delete b;} //エラー原因 a operator+(a &s){a c;c.b[0] = b[0] + s.b[0];return c;} }; void main() {a x,y;y = x + x;}

  • コレクションクラスでクラスを初期化するには

    環境: VC++.Net2008 C++/CLI Windowsフォームアプリケーション .Net、C++どちらも初めてで勉強しながら作業しています。 VB6.0で開発した経験が1回だけあります。 System.Collections.Generic のListジェネリッククラスを使って、 CSVファイルから読み込んだデータをクラスに格納してフォームから入力された値を比較して同じものがあるかないかの判定を行うプログラムを作成しています。 -------------------------------------- /* データを格納するクラス */ ref class A { char* cphoge; int ihoge; } ref class Amgr { List<A^>^ HOGE; Amgr(); //コンストラクタ {     HOGE = gcnew List<A^>(); /* CSV読み込み処理 */ if(もうCapacityがなかったら) { addで増やす } } } ---------------------------------------- CSV読み込み処理内でHOGE.add(クラス)で容量を増やした後、 読み込んだデータを代入しているのですが、 実行時エラーでSystem.nullreferenceexceptionが起きてしまいます。 調べて要は初期化がちゃんとできていない状態でアクセスしようとしたために実行時エラーで落ちたことはわかったのですが、 肝心の初期化の仕方がわかりません。どなたかご存知の方いましたらご教授よろしくお願い致します。

専門家に質問してみよう