Подтвердить что ты не робот

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

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

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

enum MyEnum { myVal1, myVal2 };

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

public enum MyEnum { myVal1, myVal2 };

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

4b9b3361

Ответ 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 для обоих способов использования.

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

Удачи,