2009-06-05 11 views
16

C'è un modo per condividere una definizione enum tra C++ (gestito) nativo (non gestito) e (gestito)?È possibile condividere una dichiarazione enum tra C# e C++ non gestito?

Ho il seguente enum utilizzato nel codice non gestito completamente:

enum MyEnum { myVal1, myVal2 }; 

La nostra applicazione a volte usa un componente gestito. Quel componente C# ottiene i valori della voce enum come ints tramite una DLL di interoperabilità C++ gestita (dalla dll nativa). (L'interoperabilità dll solo carichi se è necessario il componente C#). La # componente C ha duplicato la definizione enum:

public enum MyEnum { myVal1, myVal2 }; 

C'è un modo per eliminare la duplicazione senza girare la dll C++ nativo in una DLL gestita?

risposta

15

È possibile utilizzare un singolo file con estensione cs e condividerlo tra i due progetti. #include in C++ su un file .cs non dovrebbe essere un problema.

Questo sarebbe un esempio di file .cs:

#if !__LINE__  
namespace MyNamespace 
{ 
    public 
#endif 

// shared enum for both C, C++ and C# 
enum MyEnum { myVal1, myVal2 }; 

#if !__LINE__ 
} 
#endif 

Se si desidera che più enumerazioni in un unico file, è possibile fare questo (anche se bisogna definire temporaneamente pubblico di essere nulla per C/C++):

#if __LINE__ 
#define public 
#else 
namespace MyNamespace 
{ 
#endif 

    public enum MyEnum { MyEnumValue1, MyEnumValue2 }; 
    public enum MyEnum2 { MyEnum2Value1, MyEnum2Value2 }; 
    public enum MyEnum3 { MyEnum3Value1, MyEnum3Value2 }; 

#if __LINE__ 
#undef public 
#else 
} 
#endif 
+4

In alternativa #if! __ cplusplus public ... – user7116

+1

Ho appena provato qualcosa di simile - ma il file si chiama MyEnum.cs. In modo che compila è C# senza regole speciali. Nel mio file C++ funziona: #include "MyEnum.cs" –

+0

Impressionante, felice che tu abbia funzionato! – jjxtra

0

C++ e C# non gestiti vivono in due mondi diversi, quindi non c'è modo di utilizzare la stessa enumerazione, senza modificare la DLL C++ in una gestita.

E anche in questo caso, probabilmente avresti bisogno della duplicazione nella DLL C++ gestita.

Un enum di C++ è molto simile a un elenco di costanti, mentre un enum di C# eredita la classe Enum e quindi fornisce alcuni "trucchi". Quindi, come potete vedere, sono molto diversi.

Se non importa se la DLL C++ nativa è nativa o gestita, la trasformo in una gestita e avvolgo le chiamate native all'interno di un C++ Layer gestito.

In questo modo si può avere la duplicazione enum all'interno del ++ DLL C, ed inoltre è possibile sbarazzarsi di tutta l'interoperabilità, allo stesso tempo :-)

+0

Purtroppo, il nativo dll non può essere gestito. –

3

È possibile esporre la libreria C# per COM e quindi importare il digita libreria nel codice non gestito: in questo modo sarai in grado di utilizzare l'enumerazione definita nella libreria C# nella libreria non gestita.

+0

Questo è un approccio interessante. Ha l'effetto collaterale che un enum altrimenti non scoperto diventa pubblico COM. Sfortunatamente, la libreria C# potrebbe non funzionare mai eseguire/caricare a causa dell'incompatibilità del framework sui SO di destinazione. –

+0

@sean, è possibile rendere selettivamente enumerazioni specifiche e altri che non utilizzano ComVisibleAttribute. –

0

Ho avuto lo stesso problema in passato e l'ho risolto usando le definizioni del preprocessore.

Nel codice non gestito, all'interno di un'intestazione che può anche essere inclusa dal wrapper gestito, posizionare gli elementi di enumerazione in un #define.

Quindi, nelle definizioni di enumerazione gestita e non gestita, utilizzare la stessa #define per entrambi gli usi.

Il movimento delle enumerazioni tra il mondo gestito e non gestito sembra leggermente sgradevole (in pratica è necessario un cast), ma per il chiamante nel mondo non gestito, sembrerà e andrà bene.

Buona fortuna,

+1

Mi manca qualcosa ... usare un'intestazione in C#? –

4

Grazie per la condivisione!

Ho suonato in giro un po 'e hanno trovato un modo per avere enum multipla e dichiarazioni di costanti senza avere tonnellate di linee extra :)

// This is a valid C, C++ and C# file :) 
#if __LINE__ 
#define public 
#else 
namespace MyCSharpNamespace{ 
#endif 

    public enum MyConstant { MaxStr = 256 }; 
    public enum MyEnum1{ MyEnum1_A, MyEnum1_B }; 
    public enum MyEnum2{ MyEnum2_A, MyEnum2_B }; 

#if __LINE__ 
#undef public 
#else 
} 
#endif 

Ricordatevi di assegnare un nome al file * .cs

Problemi correlati