Como declarar identificadores em tipos nativos
Você não pode declarar um tipo de identificador em um tipo nativo. O vcclr.h fornece o modelo de encapsulamento fortemente tipado gcroot
para fazer referência a um objeto do CLR no heap do C++. Esse modelo permite inserir um identificador virtual em um tipo nativo e tratá-lo como se fosse o tipo subjacente. Na maioria dos casos, você pode usar o objeto gcroot
como o tipo inserido sem nenhuma conversão. No entanto, com for each, in você precisa usar static_cast
para recuperar a referência gerenciada subjacente.
O modelo gcroot
é implementado usando as facilidades da classe de valor System::Runtime::InteropServices::GCHandle, que fornece "identificadores" no heap de do lixo coletado. Observe que os próprios identificadores não são coletados e são liberados quando não estão mais em uso pelo destruidor na classe gcroot
(esse destruidor não pode ser chamado manualmente). Se você criar uma instância de um objeto gcroot
no heap nativo, deverá chamar a exclusão nesse recurso.
O runtime manterá uma associação entre o identificador e o objeto do CLR ao qual ele faz referência. Quando o objeto do CLR for movido com o heap do lixo coletado, o identificador retornará o novo endereço do objeto. Uma variável não precisa ser fixada para ser atribuída a um modelo gcroot
.
Exemplos
Este exemplo mostra como criar um objeto gcroot
na pilha nativa.
// mcpp_gcroot.cpp
// compile with: /clr
#include <vcclr.h>
using namespace System;
class CppClass {
public:
gcroot<String^> str; // can use str as if it were String^
CppClass() {}
};
int main() {
CppClass c;
c.str = gcnew String("hello");
Console::WriteLine( c.str ); // no cast required
}
hello
Este exemplo mostra como criar um objeto gcroot
no heap nativo.
// mcpp_gcroot_2.cpp
// compile with: /clr
// compile with: /clr
#include <vcclr.h>
using namespace System;
struct CppClass {
gcroot<String ^> * str;
CppClass() : str(new gcroot<String ^>) {}
~CppClass() { delete str; }
};
int main() {
CppClass c;
*c.str = gcnew String("hello");
Console::WriteLine( *c.str );
}
hello
Este exemplo mostra como usar gcroot
para manter referências a tipos de valor (não tipos de referência) em um tipo nativo usando gcroot
no tipo demarcado.
// mcpp_gcroot_3.cpp
// compile with: /clr
#include < vcclr.h >
using namespace System;
public value struct V {
String^ str;
};
class Native {
public:
gcroot< V^ > v_handle;
};
int main() {
Native native;
V v;
native.v_handle = v;
native.v_handle->str = "Hello";
Console::WriteLine("String in V: {0}", native.v_handle->str);
}
String in V: Hello