2009-02-24 3 views
0

В моем последнем вопросе я спросил о запуске C# -формы в программе C++-cli. У меня это работает, но у меня проблемы. Я постараюсь быть кратким.C# form в C++-программе

Моя программа на C++ должна выполнить форму C# и выполнить в ней некоторые простые функции (увеличение счетчиков и их отображение). Однако я не знаю, как это сделать. У меня есть форма инициализирована в функции инициализации:

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 (this == null), поэтому я могу использовать код функции incCounter, но не переменные класса. Странно, как если бы программа располагала FormProject.

C#

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

Что я делаю неправильно? Я фактически отключил форму и просто использовал функцию и переменные в случае, если проблема связана с пользовательским интерфейсом (invoke и так). Выходит ли из функции C++ init (первый кусок кода) очистка Form1?

ответ

0

Угадать будет то, что * ptForm1 не является достаточным, чтобы CLR считал его ссылкой. Может быть, это должно быть Form1 ^^ ptForm? Или почему вы просто не добавляете переменную form1, как вы указали глобальный указатель?

+0

Это не позволит мне иметь ручку к ручке, просто указатель на ручку. У меня есть это, поэтому я могу вызывать функции формы из других функций. – Hiperi0n

+0

Кроме того, это не позволит мне иметь дескрипторы как глобальные переменные, странно, но это единственный способ заставить его работать – Hiperi0n

+0

Тогда я предполагаю, что как только form1 выходит из сферы действия, GC будет распоряжаться им. Что делать с новым, а затем вручную удалять его? На самом деле я этого не делал сам, но, скорее всего, мне придется делать это в ближайшее время, поэтому мне интересно узнать, что вы узнали! :-) –

0

Я думаю, что вы должны просто хранить дескриптор в глобальном (то есть статическом) объекте или, по крайней мере, в статическом поле удобного класса для использования. Как и данбистром, сохранение указателя на ссылку формы не помешает сборщику мусора вернуть форму после того, как исходный дескриптор станет нулевым.

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

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

// Globals::MyForms still exists! 

Хотя я подозреваю, что ссылка на форму, ссылающаяся на нуль, означает, что что-то еще не так.

1

Если вы должны взять адрес объекта .NET в управляемой куче, поместите его в pin_ptr<>, чтобы GC не перемещал его. Это может быть источником вашей проблемы.