2011-12-04 11 views
8

Sto lavorando per incorporare il mono in un'applicazione che sto creando e non sono andato molto lontano, ma una delle cose che non riesco a trovare è come dire mono quando sto usando un oggetto e fatto con un oggetto.Mono incorporato: mantenere i riferimenti agli oggetti C# in C++

Voglio mantenere un riferimento a un oggetto C# per chiamare i metodi finché la vita del suo oggetto parallelo in C++ è finita, a quel punto, voglio dire a mono che l'oggetto C# è sicuro da raccogliere.

Come è stato realizzato?

+0

Conosco ['gcroot'] (http://msdn.microsoft.com/en-us/library/481fa11f (VS.80) .aspx) per l'implementazione .NET di Microsoft, ma non sono sicuro se questo esisterà per Mono. Dubito che questa interfaccia gestita possa essere portabile. –

+0

Ho avuto lo stesso problema e l'ho risolto avendo un campo statico sul lato gestito a cui ho assegnato l'oggetto in modo che non venisse mai raccolto. –

risposta

3

Sembra che quello che sto cercando è mono_gchandle_new e tenere il manico, non il MonoObject *, e utilizzare mono_gchandle_get_target quando ne ho bisogno.

mono_gchandle_new consente di bloccare quando si crea l'handle, ma è possibile bloccare dopo il fatto?

+1

Non è possibile eseguire il pin dopo il fatto, ma è possibile creare un nuovo gchandle bloccato. –

+0

Buona chiamata. Grazie. – Jeff

0

Una cosa da tenere a mente quando si utilizza mono_gchandle_new() che ho incontrato .. manterrà solo l'oggetto C# a cui si fa riferimento in memoria, ma se quell'oggetto alloca altri oggetti questi sono ancora soggetti alle routine di garbage collection. Il fatto che un oggetto per il quale hai una maniglia, possa avere i suoi sotto oggetti liberati su di te mi ha causato un po 'di problemi.

Attualmente sto scavando nel sistema GC mono per vedere se riesco a correggerlo in modo che tratterà quegli oggetti come oggetti radice.

Se si dispone di un numero di oggetti sufficiente (< 4096), è possibile utilizzare mono_gc_register_root() ... possiamo avere migliaia di oggetti, quindi questo non va bene per i nostri usi.

AGGIORNAMENTO: Quindi non ero corretto su questo, ci eravamo agganciati al sistema di assegnazione degli oggetti mono e non stavamo passando la variabile "atomica" correttamente sulle funzioni di allocazione GC. "Atomico" significa qualcosa di diverso dal GC, non ha nulla a che fare con l'accesso concorrente, in realtà significa che la memoria assegnata fa riferimento ad altri oggetti (atomico = 0) o no (atomico = 1).

+0

Questo è ... strano. La versione di Microsoft, 'clr :: gcroot', è un sottile involucro attorno a' Sistema :: GCHandle'. 'System :: GCHandle' serve sicuramente come root e protegge tutti gli oggetti raggiungibili direttamente o indirettamente da esso. Se questo non funziona, forse basta usare il valore numerico di 'Sistema :: GCHandle'? –

+0

Sì, è strano .. stiamo probabilmente cercando di usare mono in un modo in cui non è stato usato prima onestamente. Ho avvolto l'oggetto C# con un oggetto C++ e utilizzo il nostro sistema di riflessione interno per accedere ai dati mono da C++. Penso che questo confonda il sistema GC in mono, quindi prendi il mio commento sopra con un pizzico di sale. –

0

Utilizzare System::GCHandle::Alloc e chiamare ToIntPtr sul risultato per ottenere un token e proteggere l'oggetto dalla raccolta. Chiama ToPointer() e archivia come void*.

Utilizzare System::GCHandle::FromIntPtr quando è necessario associare il token all'oggetto o rilasciarlo in modo che sia di nuovo idoneo per la raccolta.

Problemi correlati