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

StackOverflow https://stackoverflow.com/questions/954321

Вопрос

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

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

enum MyEnum { myVal1, myVal2 };

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

public enum MyEnum { myVal1, myVal2 };

Есть ли способ устранить дублирование, не превращая собственную dll C++ в управляемую 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 и, таким образом, предоставляет немало «хитростей».Итак, как вы можете видеть, они очень другой.

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

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

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

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

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

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

Удачи,

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top