Можно ли разделить объявление enum между C # и неуправляемым C ++? - PullRequest
18 голосов
/ 05 июня 2009

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

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

enum MyEnum { myVal1, myVal2 };

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

public enum MyEnum { myVal1, myVal2 };

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

Ответы [ 5 ]

17 голосов
/ 05 июня 2009

Вы можете использовать один файл .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
4 голосов
/ 23 апреля 2012

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

Я немного поиграл и нашел способ иметь несколько объявлений enum и констант без тонны лишних строк:)

// 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 голосов
/ 05 июня 2009

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

0 голосов
/ 05 июня 2009

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

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

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

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

Удачи,

0 голосов
/ 05 июня 2009

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

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

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

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

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

...