2009-06-05 7 views
16

Existe-t-il un moyen de partager une définition enum entre le C++ natif (non géré) et le C# (géré)?Est-il possible de partager une déclaration enum entre C# et C++ non managé?

J'ai l'ENUM suivant utilisé dans le code administrable:

enum MyEnum { myVal1, myVal2 }; 

Notre application utilise parfois un composant géré. Ce composant C# obtient les valeurs de l'élément enum en tant qu'ints via une DLL d'interopérabilité C++ gérée (à partir de la DLL native). (Le dll Interop charge uniquement si le composant C# est nécessaire.) Le composant C# a dupliqué la définition enum:

public enum MyEnum { myVal1, myVal2 }; 

Y at-il un moyen d'éliminer la duplication sans tourner le natif C++ dll dans un dll géré?

Répondre

15

Vous pouvez utiliser un seul fichier .cs et le partager entre les deux projets. #include en C++ sur un fichier .cs ne devrait pas poser de problème.

Ce serait un exemple de fichier .cs:

#if !__LINE__  
namespace MyNamespace 
{ 
    public 
#endif 

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

#if !__LINE__ 
} 
#endif 

Si vous voulez plusieurs énumérations dans un fichier, vous pouvez le faire (bien que vous devez définir temporairement du public à rien pour 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

Alternativement #if! __ cplusplus public ... – user7116

+1

Je viens de tester quelque chose de similaire - mais le fichier s'appelle MyEnum.cs. Alors qu'il compile est C# sans règles spéciales. Dans mon fichier C++ cela fonctionne: #include "MyEnum.cs" –

+0

Génial, content de l'avoir fait fonctionner! – jjxtra

0

Unmanaged C++ et C# vivent dans deux mondes différents, donc pas il n'y a pas moyen d'utiliser la même ENUM, sans changer le C++ DLL dans un géré.

Et même alors, vous auriez probablement besoin de la duplication dans la DLL C++ gérée.

A C++ ENUM est un peu comme une liste des constantes, alors qu'un C# ENUM hérite de la classe Enum, et fournit ainsi un tout à fait quelques "trucs". Donc, comme vous pouvez le voir, ils sont très différent.

Si elle n'a pas d'importance si la DLL C++ natif est natif ou géré, je le transformer en une gestion et envelopper les appels natifs à l'intérieur d'une gestion C++ couche.

De cette façon, vous pouvez avoir la duplication enum dans la DLL C++, et vous pouvez vous débarrasser de tous les Interop en même temps :-)

+0

Malheureusement, le natif dll ne peut pas être géré. –

3

Vous pouvez exposer la bibliothèque C# pour COM et puis importer le tapez la bibliothèque dans le code non managé - de cette façon, vous serez en mesure d'utiliser l'enum défini dans la bibliothèque C# dans la bibliothèque non managée.

+0

C'est une approche intéressante. Il a l'effet secondaire qu'une énumération non exposée devient COM publique. Malheureusement, la bibliothèque C# peut ne pas s'exécuter/charger en raison d'une incompatibilité de structure sur les systèmes d'exploitation cibles. –

+0

@sean, vous pouvez sélectivement rendre public enums spécifiques et d'autres ne pas utiliser le ComVisibleAttribute. –

0

J'ai rencontré le même problème dans le passé et l'ai résolu en utilisant des définitions de préprocesseur.

Dans votre code non géré, à l'intérieur d'un en-tête qui peut également être inclus par votre wrapper managé, placez vos objets de dénombrement en un #define.

Ensuite, dans votre énumération gérés et non gérés définitions, utilisez la même #define pour les deux usages. Le mouvement des énumérations entre le monde géré et non géré semble légèrement désagréable (fondamentalement une distribution est nécessaire), mais à votre appelant dans le monde non géré, il va regarder et se sentir bien.

Bonne chance,

+1

Il me manque quelque chose ... utilisez un en-tête en C#? –

4

Merci pour le partage!

J'ai joué un peu et trouvé un moyen d'avoir plusieurs ENUM et déclarations constantes sans avoir des tonnes de lignes supplémentaires :)

// 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 

Rappelez-vous le nom de votre fichier * .cs

Questions connexes