C ++プロジェクトとC#プロジェクトを持つソリューションがあります。
C ++プロジェクトは、C#でインスタンス化して、そのメンバー関数を呼び出すクラスを定義します。これまでのところ、クラスをインスタンス化することができました。
CFoo Bar = new CFoo();
しかし、私がその関数を呼び出そうとすると、コンパイラーはそれが利用できないと言います。
また、デバッガーでオブジェクトを検査すると、メンバーが表示されません。
ここで何が欠けていますか?
C ++/CLIでクラスをとして宣言する必要がありますref class
。
(C++ではなくC++ / CLIについて話していることに注意してください。C++プロジェクトでCLRを有効にしておく必要があります。そうしないと、新しいCFoo
ものを機能させることができません。)
編集:
古いクラスをすべてクラスに変換する必要はありませんref
。
古いC++があるとします。
class FooUnmanaged
{
int x;
FooUnmanaged() : x(5) {}
};
次に、それをCLRクラスでラップしようとします。
ref class FooManaged
{
FooUnmanaged m;
};
お気づきのとおり、これは許可されていないというエラーが表示されます。しかし、これを試してください:
ref class FooManaged
{
FooUnmanaged *m;
};
それは完全に大丈夫です。コンパイラーは、マネージヒープ上のオブジェクト内に埋め込まれたアンマネージオブジェクトのインスタンスを割り当てたくありませんがSystem.IntPtr
、結果のILに変換されるポインターを持っていることは非常に喜ばしいことです。
これは、の呼び出し方法を決定する必要があることを意味しますdelete
。最も可能性の高い解決策は次のとおりです。
ref class FooManaged
{
FooUnmanaged *u;
public:
FooManaged(FooUnmanaged *u_)
: u(u_) { }
~FooManaged() { delete u; }
};
他のC++クラスと同じように。将来のバージョンでは、C ++/CLIがこの変換を自動的に実行できるようになる可能性があります。
結果として得られるILは、FooManaged
クラスがに実装されIDisposable
、デストラクタがDispose
メソッドに変換されたことに注意してください。これにより、.NETクライアントはC#などで適切に割り当てを解除できます。
using (var m = new FooManaged())
{
// end of block: m will be disposed (and so FooUnmanaged will be deleted)
}