- - PR -
C#でアンマネージドC++クラスを使う
1
投稿者 | 投稿内容 | ||||
---|---|---|---|---|---|
|
投稿日時: 2007-12-17 13:07
既に作成済みのアンマネージドC++のコードをVS2003C++とVS2005C#で共用したいと考えています。 VS2003C++にて、アンマネージドのクラス、それをラップするマネージドのクラスをDLL化しておけば、 VS2005C#でもDLLを参照すれば共用できると考えて、試しているのですがうまくいきません。 詳細ですが VS2003のC++にて、 アンマネージドのC++クラスとそれをラップしたマネージドのC++クラスが含まれているDLLを作成しました。 コードとしては、ネットですぐに見つかるアンマネージドラップのサンプルそのままです。 試しに、VS2003C++にて別のプロジェクトを作成し、DLLを参照してマネージドのクラスを使ってみたら、 ラップのクラスとして、期待通りに動きました。 今度はVS2005のC#にてそのDLLを参照してマネージドのクラスを使ってみると、 アンマネージドのクラスを使用する部分(コンストラクタ)でSystem.StackOverflowExceptionが発生し、落ちてしまいます。 VS2003で参照した時は動いていたので、単純なコード記述ミスでStackOverflowExceptionが出ている訳ではないと思うのですが。 構造として間違ったものになっているのではないか?と行き詰まり、ご意見を頂きたく、投稿してみました。 宜しくお願いします。 | ||||
|
投稿日時: 2007-12-17 13:23
どんなコードが見せていただかないと分かりません。
_________________ 囚人のジレンマな日々 | ||||
|
投稿日時: 2007-12-17 13:49
コードは以下のようになっております。 下記のmyLib.cpp、myLib.h、VS2003C++でDLLを作成しました。 ---<myLib.h>---- #pragma once #using <mscorlib.dll> class __declspec(dllexport) MyClass { private: int a,b,c; //プライベート変数 public: MyClass(); //コンストラクタ ~MyClass(); //ディストラクタ void SetData(int,int); //プライベート変数に値を設定 int GetData(); //プライベート変数Cの値を取得 void Calc(); //単に内部で c=a+bを計算する }; namespace testSpace { public __gc class MClass { public: MClass() { m_pC = new MyClass(); } ~MClass() { delete this->m_pC; } void SetData_f(int a,int b) {this->m_pC->SetData(a,b);} int GetData_f(){return this->m_pC->GetData();} void Calc_f(){this->m_pC->Calc();} private: MyClass * m_pC; }; }; ---<myLib.h ここまで>---- ---<myLib.cpp>---- #include <windows.h> #include "myLib.h" extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { switch(dwReason) { case DLL_PROCESS_ATTACH: //初期処理 break; case DLL_PROCESS_DETACH: //終了処理 break; } return 1; // OK } MyClass::MyClass() { a = b = c = 0; } MyClass::~MyClass() { } void MyClass::SetData(int p1,int p2) { a=p1; b = p2; } int MyClass::GetData() { return c; } void MyClass::Calc() { c = a+b; } ---<myLib.cpp ここまで>---- そのDLLをVS2005C#にて参照し、 testSpace.MClass m = new testSpace.MClass(); このようにインスタンスを生成したところで、StackOverflowExceptionが発生します。 | ||||
|
投稿日時: 2007-12-17 14:19
m_pC = new MyClass();
ここの MyClass がどこのクラスを指しているんだって話だと思います。別の名前にしたらいかがでしょう。 あと、マネージ C++ の DLL に DllMain は必要ないと思いますが。アンマネージの DLL をエクスポートする気がないなら __declspec(dllexport) は必要ないですし(そもそもアンマネージC++クラスをエクスポートするのは一癖ありますが)。 更に言うと、VC++ 2003 で生成されるアセンブリは .NET1.1、VC#2005で生成されるアセンブリは .NET2.0が対象ですよね。まぁ動かない事はないと思いますが、どちらも 2.0 環境で動きますよ。 _________________ 囚人のジレンマな日々 | ||||
|
投稿日時: 2007-12-17 15:10
ご指摘有り難うございます。 区別がはっきりつくように、アンマネージドのクラス名を変えて、アンマネージドクラスのほうも違うnamespaceでくくりました。 __declspec(dllexport) 、DllMainも外しました。 それでも現象は変わりませんでした。 DLLを提供する先がまだVS2003C++で開発しているようなので、そこに合わせて作っておき、こちらはVS2005C#で引き込めばいいかな、という所からの出発です。 実現できていないので、合わせるという考え方がよくないのかな??など迷走しております。 | ||||
|
投稿日時: 2007-12-17 15:21
で、どんなコードになったんでしょうか。 _________________ 囚人のジレンマな日々 | ||||
|
投稿日時: 2007-12-17 15:33
ご指摘を元に、以下のようなコードに変更いたしました。 ---<myLib.h>---- #pragma once #using <mscorlib.dll> namespace Unmanaged; { class UnmanagedClass { private: int a,b,c; //プライベート変数 public: UnmanagedClass(); //コンストラクタ ~UnmanagedClass(); //ディストラクタ void SetData(int,int); //プライベート変数に値を設定 int GetData(); //プライベート変数Cの値を取得 void Calc(); //単に内部で c=a+bを計算する }; }; namespace testSpace { public __gc class MClass { public: MClass() { m_pC = new Unmanaged::UnmanagedClass(); } ~MClass() { delete this->m_pC; } void SetData_f(int a,int b) {this->m_pC->SetData(a,b);} int GetData_f(){return this->m_pC->GetData();} void Calc_f(){this->m_pC->Calc();} private: Unmanaged::UnmanagedClass * m_pC; }; }; ---<myLib.h ここまで>---- ---<myLib.cpp>---- #include <windows.h> #include "myLib.h" namespace Unmanaged { TestUnmanagedClass::TestUnmanagedClass() { a = b = c = 0; } TestUnmanagedClass::~TestUnmanagedClass() { } void TestUnmanagedClass::SetData(int p1,int p2) { a=p1; b = p2; } int TestUnmanagedClass::GetData() { return c; } void TestUnmanagedClass::Calc() { c = a+b; } }; ---<myLib.cpp ここまで>---- | ||||
|
投稿日時: 2007-12-17 15:39
間違って、書き込んでしまいました。 改めて。 以下のようなコードに修正してみました。 ---<myLib.h>---- #pragma once #using <mscorlib.dll> namespace Unmanaged; { class UnmanagedClass { private: int a,b,c; //プライベート変数 public: UnmanagedClass(); //コンストラクタ ~UnmanagedClass(); //ディストラクタ void SetData(int,int); //プライベート変数に値を設定 int GetData(); //プライベート変数Cの値を取得 void Calc(); //単に内部で c=a+bを計算する }; }; namespace testSpace { public __gc class MClass { public: MClass() { m_pC = new Unmanaged::UnmanagedClass(); } ~MClass() { delete this->m_pC; } void SetData_f(int a,int b) {this->m_pC->SetData(a,b);} int GetData_f(){return this->m_pC->GetData();} void Calc_f(){this->m_pC->Calc();} private: Unmanaged::UnmanagedClass * m_pC; }; }; ---<myLib.h ここまで>---- ---<myLib.cpp>---- #include <windows.h> #include "myLib.h" namespace Unmanaged { UnmanagedClass::UnmanagedClass() { a = b = c = 0; } UnmanagedClass::~UnmanagedClass() { } void UnmanagedClass::SetData(int p1,int p2) { a=p1; b = p2; } int UnmanagedClass::GetData() { return c; } void UnmanagedClass::Calc() { c = a+b; } }; ---<myLib.cpp ここまで>---- [/quote] |
1