2010-06-16 2 views
8

È possibile chiamare CLR DLL (uno ad esempio realizzato con C#) dal codice C++ non gestito?È possibile chiamare una DLL gestita da C++ non gestito?

Ho bisogno di una DLL che non è in grado di chiamarla in qualche modo, forse anche tramite un processo proxy C++ che è stato creato con C++/CLI?

+2

Puoi avvolgere che DLL gestita in un eseguibile che è un'app console e accetta argomenti da riga di comando, mentre sputa il suo risultato su 'stdout'. Puoi quindi chiamarlo come faresti con qualsiasi altro exe. Non ideale, ma potrebbe funzionare. Spero che non stiate usando più thread, perché non so se funzionerà allora. –

+1

Hai dato la risposta da solo. Scrivi un proxy in C++/CLI (o C++. C++ netto o gestito o come viene chiamato oggi), quindi chiama questo proxy dal tuo codice C++ non gestito. – Patrick

+0

forse questo aiuta: http://stackoverflow.com/questions/1058897/can-c-cli-be-used-to-call-net-code-from-native-c-applications – smerlin

risposta

6

La DLL CLR dovrebbe essere creata come un assembly visibile COM. Se hai il controllo del C#, è una ricostruzione semplice, altrimenti è praticamente impossibile usarlo direttamente.

+0

@Hamish, cura di elaborare? –

+0

Aggiunto "... per usarlo direttamente." Altrimenti il ​​significato era sbagliato, mi dispiace. – SWeko

+0

@SWeko: c'è sempre Reverse PInvoke. Quindi non è impossibile. – Aamir

5

@SWeko ha fornito la risposta migliore se è possibile modificare la DLL originale e il codice non gestito può contare sull'accesso a un apartment COM (chiamato threading con ::CoInitialize() o il thread chiamante del codice non gestito ha una coerenza appartamento).

Se ciò non è il caso, la soluzione migliore è creare una DLL C++ "gestita" come wrapper nell'assembly C# gestito. Si chiama C++/CLI. È possibile esporre le operazioni API C non gestite e all'interno dell'implementazione di quelle, delegare alle API gestite. Funziona piuttosto bene e diversamente dalle API COM, non ci sono problemi di affinità con i thread.

4

Non sono sicuro che si adatti, ma forse "Reverse PInvoke" è un'opzione.

Se è possibile chiamare prima dal C# al proprio C++, è possibile fornire un delegato .net al C++ in cui è possibile utilizzarlo come puntatore a funzione. Puoi quindi chiamare dal tuo C++ a C# usando quel puntatore di funzione.

public delegate int Read(int target); 
[DllImport("yourC++.dll")] 
static extern void RegisterRead(Read x); 
Read m_Read = new Read(yourClass.Read); 

RegisterRead(m_Read); 

Ci possono essere alcuni trucchi con il GC raccogliendo il delegato presto, qualsiasi classe ha il delegato può essere necessario appuntato se non viene solo utilizzato immediatamente in RegisterRead