Можно ли делиться объявлением enum между С# и неуправляемым С++?
Есть ли способ поделиться определением перечисления между нативным (неуправляемым) С++ и (управляемым) С#?
У меня есть следующее перечисление, используемое в полностью неуправляемом коде:
enum MyEnum { myVal1, myVal2 };
В нашем приложении иногда используется управляемый компонент. Этот компонент С# получает значения элемента enum как ints через управляемую dll dll С++ (из родной dll). (Взаимодействие dll загружается только в том случае, если требуется компонент С#.) Компонент С# продублировал определение перечисления:
public enum MyEnum { myVal1, myVal2 };
Есть ли способ устранить дублирование, не превращая исходную С++ dll в управляемую dll?
Ответы
Ответ 1
Вы можете использовать один файл .cs и делиться им между обоими проектами. #include
в С++ в файле .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/С++):
#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
Ответ 2
Спасибо за обмен!
Я немного поиграл и нашел способ иметь несколько перечислений и константных объявлений без лишних строк:)
// 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
Ответ 3
Вы можете открыть библиотеку С# для COM, а затем импортировать библиотеку типов в неуправляемый код - таким образом вы сможете использовать перечисление, определенное в библиотеке С# в неуправляемой библиотеке.
Ответ 4
Неуправляемые С++ и С# живут в двух разных мирах, поэтому нет никакого способа использовать одно и то же перечисление, не изменяя DLL С++ в управляемый.
И даже тогда вам, вероятно, потребуется дублирование в управляемой С++ DLL.
Перечисление С++ очень похоже на список констант, тогда как С# enum наследует класс Enum и, следовательно, предоставляет довольно много "трюков". Итак, как вы можете видеть, они очень разные.
Если неважно, является ли родная С++ DLL родной или управляемой, я бы превратил ее в управляемый и обернул собственные вызовы внутри управляемого С++ Layer.
Таким образом, вы можете иметь дублирующее перечисление внутри С++ DLL, а также вы можете избавиться от всего взаимодействия в одно и то же время: -)
Ответ 5
У меня была такая же проблема в прошлом, и я решил ее использовать определения препроцессора.
В неуправляемом коде внутри заголовка, который также может быть включен вашей управляемой оболочкой, поместите элементы перечисления в #define.
Затем в ваших управляемых и неуправляемых определениях перечисления используйте одно и то же #define для обоих способов использования.
Движение перечислений между управляемым и неуправляемым миром выглядит слегка противным (в основном требуется бросок), но для вашего вызывающего абонента в неуправляемом мире он будет выглядеть и чувствовать себя хорошо.
Удачи,