Ho una libreria di base in C++ e l'applicazione client è in C#. C'è l'interfaccia C++/cli per accedere a C++ api da C#. Ogni cosa funziona bene fino a quando non entrano in gioco più domini di app come NUnit o WCF hosting con un dominio app.Impossibile passare un GCHandle attraverso AppDomain: soluzione senza delegati?
Ho memorizzato l'oggetto gestito in gcroot in cli per la richiamata. Ho letto che questa è la causa principale del problema del dominio dell'app ("Impossibile passare un GCHandle attraverso AppDomains") perché non dispongono di informazioni sul dominio dell'app (http://lambert.geek.nz/2007/05/29/unmanaged-appdomain-callback/). qualcuno ha suggerito di usare delegati ma il mio strato C++ sottostante si aspetta un puntatore oggetto non funzionante (http://www.lenholgate.com/blog/2009/07/error-cannot-pass-a-gchandle-across-appdomains.html). Ho anche provato IntPtr ma in questo caso non sono in grado di trasmetterlo al mio oggetto gestito durante i callback.
UPDATE
Vorrei esporre il mio problema un po 'più.
I Classe "ricevitore" in C# e viene passato come parametro di input a una delle API. Questo oggetto ricevente viene utilizzato per la richiamata. In C++/CLI ho creato una classe nativa/non gestita "ObjectBinder" che è la stessa replica (ha gli stessi metodi) della classe Receiver gestita. Contiene riferimento dell'oggetto destinatario gestito in gcroot. Quando chiamiamo quell'api da C# viene a livello CLI e il dominio app è "client exe". archiviamo il parametro "oggetto destinatario gestito" in ObjectBinder in gcroot e passiamo il riferimento dell'oggetto ObjectBinder nativo a C++. Ora il codice di backend (C++ e c) invia un callback asyn (nuovo thread) al livello C++ che utilizza l'oggetto ObjectBinder per inviare indietro la chiamata a CLI. Ora siamo nel livello CLI nell'oggetto ObjectBinder. MA Il dominio dell'app è stato modificato (in caso di WCF o NUNIT o qualsiasi altro servizio che crea il proprio dominio app che non è noto al momento della compilazione). Ora voglio accedere all'oggetto Receiver gestito che è memorizzato in gcroot per rimandare la callback a C# ma ha dato errore APP DOMAIN.
Ho anche provato IntPtr e IUnknown * invece di gcroot con maresciallo :: GetIUnknownForObject e maresciallo :: GetObjectForIUnknown ma ottenere lo stesso errore.
Difficile capire l'aggiornamento senza visualizzare il codice effettivo. Se ho capito bene, hai un oggetto * non gestito * che contiene un puntatore dell'interfaccia COM su un oggetto * gestito * B. Si accede a un altro appdomain, dove richiama B, è giusto? Se è così, fai in modo che B derivi da "MarshalByRefObject" e vedi se questo aiuta. – Noseratio
@Noseratio Hai capito bene. –
Quindi, ha derivato 'B' da 'MarshalByRefObject' e l'accesso tramite' Marshal :: GetIUnknownForObject() 'non è stato aiutato? Inoltre, stai facendo questo sullo stesso thread (nonostante un diverso appdomain)? – Noseratio