Можно ли делиться объявлением enum между C # и неуправляемым C ++?

Есть ли способ поделиться определением enum между нативным (неуправляемым) C ++ и (управляемым) C #?

У меня есть следующее перечисление, используемое в полностью неуправляемом коде:

enum MyEnum { myVal1, myVal2 }; 

В нашем приложении иногда используется управляемый компонент. Этот компонент C # получает значения элемента enum как ints через управляемую dll dll c ++ (из родной dll). (Взаимодействие dll загружается только в том случае, если требуется компонент C #.) Компонент C # продублировал определение enums:

 public enum MyEnum { myVal1, myVal2 }; 

Есть ли способ устранить дублирование, не превращая исходную C ++ dll в управляемую dll?

Вы можете использовать один файл .cs и делиться им между обоими проектами. #include в C ++ для файла .cs не должно быть проблемой.

Это будет пример файла .cs:

 #if !__LINE__ namespace MyNamespace { public #endif // shared enum for both C, C++ and C# enum MyEnum { myVal1, myVal2 }; #if !__LINE__ } #endif 

Если вам нужно несколько перечислений в одном файле, вы можете сделать это (хотя вы должны временно определить, что public ничего не значит для 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 

Спасибо, что поделился!

Я немного поиграл и нашел способ иметь несколько перечислений и постоянных деклараций без лишних строк 🙂

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

Не забудьте указать свой файл * .cs

Вы можете открыть библиотеку C # для COM, а затем импортировать библиотеку типов в неуправляемый код – таким образом вы сможете использовать перечисление, определенное в библиотеке C # в неуправляемой библиотеке.

Неуправляемые C ++ и C # живут в двух разных мирах, поэтому нет никакого способа использовать одно и то же перечисление, не меняя c ++ DLL на управляемый.

И даже тогда вам, вероятно, потребуется дублирование в управляемой C ++ DLL.

Перечисление C ++ очень похоже на список констант, тогда как C # enum наследует class Enum и, таким образом, предоставляет довольно много «трюков». Итак, как вы можете видеть, они очень разные.

Если неважно, является ли родная C ++ DLL родной или управляемой, я бы превратил ее в управляемую и обернул собственные вызовы внутри управляемого C ++ Layer.

Таким образом, вы можете дублировать перечисление внутри C ++ DLL, а также вы можете избавиться от всего взаимодействия в одно и то же время 🙂

У меня была такая же проблема в прошлом, и я решил ее использовать определения препроцессора.

В неуправляемом коде внутри заголовка, который также может быть включен вашей управляемой оболочкой, поместите элементы enums в #define.

Затем в ваших управляемых и неуправляемых определениях перечислений используйте одно и то же #define для обоих способов использования.

Движение перечислений между управляемым и неуправляемым миром выглядит слегка противным (в основном требуется бросок), но для вашего вызывающего абонента в неуправляемом мире он будет выглядеть и чувствовать себя хорошо.

Удачи,