2013-03-27 11 views
5

È un po 'strano fare questa domanda, perché ho un codice che sembra non dovrebbe funzionare, ma lo fa, e anche se non mi lamento, mi piacerebbe confermare perché? LOLIn che modo i callback non statici funzionano dal codice nativo?

Semplicemente, ho una DLL nativa C++ (nessun CLR/supporto gestito a tutti) che richiede una richiamata dal codice C#. Il lato nativo memorizza una funzione di callback stdcall, fornita dal lato C#. Ho sempre pensato che il callback METHOD (in C#) doveva essere statico, ma non statico e l'espressione lambda ENTRAMBI funziona JUST FINE !? Come viene eseguito il marshalling del "questo" puntatore dal codice nativo? Ho sempre pensato che il codice nativo memorizza solo i puntatori di funzione non istanza?

Ora ho trovato un articolo in cui un tizio ha emesso il codice IL per "collegare" tra callback gestiti nativi e non statici. Ho anche notato questo metodo deprezzato: "Marshal.GetUnmanagedThunkForManagedMethodPtr()". Il metodo non è più supportato, cosa che presumo significhi che sia integrato?

sintesi Domanda:

  1. È thunking ora integrato nativamente nel .NET attraverso l'emissione di codice IL? In tal caso, in quale versione di .NET è stato supportato in modo nativo?

  2. Il "thunking" implicito è supportato anche in Mono?

  3. Quando l'IL viene emesso per le richiamate gestite, cosa succede quando l'istanza a cui si riferisce il thunk viene cancellata? L'IL viene rimosso, oppure potrebbe portare a una "perdita" di memoria per così dire?

Grazie.

risposta

2

Il thunk è ora generato nativamente in .NET emettendo il codice IL? In tal caso, in quale versione di .NET è stato supportato in modo nativo?

No IL nella coinvolti nella thunk, succede emettendo codice nativo - un trampolino che riorganizza argomenti per soddisfare .NET convenzione di chiamata, tra cui il puntatore this che viene salvato in caso di delegati chiusi, e quindi esegue una coda chiamata al metodo .NET stesso.

Il "thunking" implicito è supportato anche in Mono?

Questo è chiamato "reverse p/invoke", che dovrebbe facilitare la ricerca nei documenti Mono.

Quando l'IL viene emesso per le richiamate gestite, cosa succede quando l'istanza a cui fa riferimento il thunk viene cancellata?

Quando il delegato raccoglie i rifiuti, viene liberata anche la memoria utilizzata dal trampolino. Quindi è necessario mantenere in vita il delegato finché il codice nativo ha un puntatore al trampolino.

+0

Grazie. È un peccato, come al solito, questa roba è così astratta senza alcuna documentazione adeguata. :/Appena sotto la pelle, ma comunque ...;) Sto imparando molto di più sul marshalling da quando ho avviato un wrapper gestito V8 per il mio take su un server basato su JavaScript: https: //dreamspace.codeplex. com / –

1

Il marshaller di interoperabilità effettua il marshalling di un delegato. Il delegato può essere un delegato di classe (no this) o un delegato di istanza (ha un this). Dal punto di vista di C#, sta chiamando un delegato. vale a dire la stessa semantica utilizzata per gestire this con un delegato di istanza (ad esempio il disaccoppiamento dell'istanza di classe) viene effettivamente utilizzata.

Ovviamente ci sono altre cose sotto le coperte con altre cose (come pinning, ecc.) - ma in genere non sono correlate a ciò che hai chiesto.

+0

Ho fatto questo, ma è bello dichiararlo esplicitamente per gli altri, poiché ho avuto difficoltà a trovare informazioni solide su di esso. ;) –

Problemi correlati