0

前回の質問で、C++-cli プログラムで C# フォームを実行することについて尋ねました。動作するようになりましたが、問題が発生しています。私は簡潔にしようとします。

私の C++ プログラムは、C# フォームを実行し、その中でいくつかの単純な関数を実行する必要があります (カウンターを増やして表示する)。ただし、これを行う最善の方法はわかりません。init 関数で初期化されたフォームがあります。

C++-cli

SUTAdapter::Form1^ *ptForm1; // Global variable

...

FormProject::Form1^ form1;
form1 = gcnew FormProject::Form1();
ptForm1 = &form1;
(*ptForm1)->Show();
(*ptForm1)->incCounter(0);

C++ プログラムの他の一部の関数は、単に incCounter を呼び出します。私の問題は、別の関数から incCounter への 2 回目の呼び出しで C# Form1 が null (this == null) になるため、incCounter の関数コードを使用できますが、クラス変数は使用できません。プログラムが FormProject を破棄したかのように、奇妙です。

C#

public void incCounter(int counter)
{
  int param1 = counter;
  this.count[counter]++; // this == null in sucessive calls from c++ program
}

私は何を間違っていますか?問題がUIにある場合に備えて、実際にフォームを無効にし、関数と変数を使用しています(呼び出しなど)。Form1 をクリアする C++ init 関数 (コードの最初のチャンク) を終了していますか?

4

3 に答える 3

1

マネージ ヒープ上の .NET オブジェクトのアドレスを取得する必要がある場合は、それをpin_ptr<>に入れて、GC が移動しないようにします。それがあなたの問題の原因かもしれません。

于 2009-02-25T00:36:49.897 に答える
0

私の推測では、*ptForm1 は CLR に参照としてカウントさせるのに十分ではありません。代わりに、Form1^^ ptForm にする必要がありますか? または、ポインターをグローバルに挿入するときに、form1 変数を配置しないのはなぜですか?

于 2009-02-24T10:45:42.903 に答える
0

ハンドルをグローバル(つまり静的)オブジェクト、または少なくとも使用するのに便利なクラスの静的フィールドに格納する必要があると思います。ダンビストロムが言ったように、フォーム参照へのポインターを保持しても、元のハンドルが null になると、ガベージ コレクターがフォームを再利用するのを防ぐことはできません。

static ref class Globals
{
    static FormProject::Form1^ MyForm;
}

// Later on...
Globals::MyForm = form1;
form1->DoStuff();
form1 = nullptr;

// Globals::MyForms still exists!

Form 参照が null になることは、他の何かが間違っていることを意味すると思いますが。

于 2009-02-24T14:33:59.923 に答える