2011-12-04 13 views
8

Estoy trabajando en la incrustación de mono en una aplicación que estoy creando, y no he llegado muy lejos, pero una de las cosas que parece que no puedo encontrar es cómo decir mono cuando estoy usando un objeto y hecho con un objeto.Mono incrustado: Mantener referencias a objetos C# en C++

Quiero mantener una referencia a un objeto C# para llamar a los métodos hasta que termine la vida útil de su objeto paralelo en C++, momento en el que quiero decirle a mono que el objeto C# es seguro de recopilar.

¿Cómo se logra esto?

+0

Sé de ['gcroot'] (http://msdn.microsoft.com/en-us/library/481fa11f (VS.80) .aspx) para la implementación de .NET de Microsoft, pero no estoy seguro si esto existirá para Mono. Dudo que esta interfaz de administrado a nativo sea probablemente portátil. –

+0

Tuve el mismo problema y lo resolví teniendo un campo estático en el lado administrado al que asigné el objeto para que nunca se recopile gc. –

Respuesta

3

Parece que lo que estoy buscando es mono_gchandle_new, y me agarro del asa, no del MonoObjeto *, y uso mono_gchandle_get_target cuando lo necesito.

mono_gchandle_new le permite anclar al crear el asa, pero ¿es posible anclar después?

+1

No puede anclar el hecho, pero puede crear un nuevo artículo fijo. –

+0

Buena llamada. Gracias. – Jeff

0

Una cosa a tener en cuenta al usar mono_gchandle_new() que encontré ... mantendrá solo el objeto C# al que hizo referencia en la memoria, pero si ese objeto asigna otros objetos, estos todavía están sujetos a las rutinas de recolección de basura. El hecho de que un objeto que tiene un control, puede tener sus subconjuntos liberados, me ha causado bastante problemas.

Actualmente estoy explorando el sistema mono GC para ver si puedo solucionarlo, por lo que tratará esos objetos como objetos raíz.

Si tiene pocos objetos suficientes (< 4096), puede usar mono_gc_register_root() ... podemos tener miles de objetos, por lo que esto no es bueno para nuestros usos.

ACTUALIZACIÓN: Por lo tanto, era incorrecta al respecto, nos habíamos enganchado en el sistema de asignación de objetos mono y no estábamos pasando correctamente la variable "atómica" en las funciones de asignación de GC. "Atómico" significa algo diferente al GC, no tiene nada que ver con el acceso simultáneo, en realidad significa que la memoria asignada hace referencia a otros objetos (atómico = 0) o no (atómico = 1).

+0

Eso es ... raro. La versión de Microsoft, 'clr :: gcroot', es una envoltura delgada alrededor de' System :: GCHandle'. 'System :: GCHandle' definitivamente sirve como raíz y protege todos los objetos a los que se puede acceder directa o indirectamente. Si eso no funciona, tal vez solo use el valor numérico de 'System :: GCHandle'? –

+0

Sí, es raro ... probablemente estamos tratando de usar mono de una manera que no se haya usado con honestidad. Envolví el objeto C# con un objeto C++ y utilizamos nuestro sistema de reflexión interno para acceder a los datos mono de C++. Creo que esto está confundiendo el sistema GC en mono, así que tome mi comentario anterior con un grano de sal. –

0

Usa System::GCHandle::Alloc y llama al ToIntPtr para obtener un token y proteger el objeto de la colección. Llame al ToPointer() y almacénelo como void*.

Utilice System::GCHandle::FromIntPtr cuando necesite asignar el token al objeto, o libérelo para que vuelva a ser elegible para la recopilación.