Cómo: Declarar controladores en tipos nativos
No se puede declarar un tipo de identificador en un tipo nativo. vcclr.h proporciona la plantilla contenedora con seguridad de tipos gcroot
para hacer referencia a un objeto CLR desde el montón de C++. Esta plantilla le permite insertar un identificador virtual en un tipo nativo y tratarlo como si fuera el tipo subyacente. En la mayoría de los casos, puede usar el objeto gcroot
como tipo incrustado sin ninguna conversión. Sin embargo, con for each, in, debe usar static_cast
para recuperar la referencia administrada subyacente.
La plantilla gcroot
se implementa mediante las instalaciones de la clase de valor System::Runtime::InteropServices::GCHandle, que proporciona "identificadores" en el montón recopilado por elementos no utilizados. Tenga en cuenta que los identificadores no se recopilan como elementos no utilizados y se liberan cuando ya no están en uso por el destructor de la clase gcroot
(no se puede llamar a este destructor manualmente). Si crea una instancia de un objeto gcroot
en el montón nativo, debe llamar a delete en ese recurso.
El entorno de ejecución mantendrá una asociación entre el identificador y el objeto CLR, al que hace referencia. Cuando el objeto CLR se mueve con el montón recopilado por elementos no utilizados, el identificador devolverá la nueva dirección del objeto. No es necesario anclar una variable antes de asignarla a una plantilla gcroot
.
Ejemplos
En este ejemplo se muestra cómo crear un objeto gcroot
en la pila 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
En este ejemplo se muestra cómo crear un objeto gcroot
en la pila nativa.
// 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
En este ejemplo se muestra cómo usar gcroot
para contener referencias a tipos de valor (no tipos de referencia) en un tipo nativo mediante gcroot
en el tipo con la conversión boxing aplicada.
// 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