4

C ++プロジェクトとC#プロジェクトを持つソリューションがあります。

C ++プロジェクトは、C#でインスタンス化して、そのメンバー関数を呼び出すクラスを定義します。これまでのところ、クラスをインスタンス化することができました。

CFoo Bar = new CFoo();

しかし、私がその関数を呼び出そうとすると、コンパイラーはそれが利用できないと言います。

また、デバッガーでオブジェクトを検査すると、メンバーが表示されません。

ここで何が欠けていますか?

4

1 に答える 1

9

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)
}
于 2009-07-23T10:41:36.860 に答える