在我的上一个问题中,我询问过在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的第二次调用使我的C#Form1为null(这= = null),所以我可以使用incCounter的函数代码而不是类变量。奇怪的是,好像该程序处理了FormProject。
C#
public void incCounter(int counter)
{
int param1 = counter;
this.count[counter]++; // this == null in sucessive calls from c++ program
}
我做错了什么?我实际上已经禁用了表单,只是使用函数和变量,以防问题出在UI(invoke等)。是否退出C ++ init函数(第一个代码块)清除Form1?
答案 0 :(得分:1)
如果必须在托管堆上获取.NET对象的地址,请将其放在pin_ptr<>中,以便GC不会移动它。这可能是你问题的根源。
答案 1 :(得分:0)
我的猜测将是* ptForm1不足以使CLR将其计为参考。也许它应该是Form1 ^^ ptForm,而不是?或者你为什么不把全局插入指针时放入form1变量?
答案 2 :(得分:0)
我认为你应该将句柄存储在一个全局(即静态)对象中,或者至少是一个方便类的静态字段来使用。就像danbystrom所说的那样,保持指向Form引用的指针不会阻止垃圾收集器在原始句柄变为null时回收表单。
static ref class Globals
{
static FormProject::Form1^ MyForm;
}
// Later on...
Globals::MyForm = form1;
form1->DoStuff();
form1 = nullptr;
// Globals::MyForms still exists!
虽然我怀疑Form引用为null意味着其他东西也是错误的。