2009-06-05 3 views
16

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

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

enum MyEnum { myVal1, myVal2 }; 

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

public enum MyEnum { myVal1, myVal2 }; 

Есть ли способ, чтобы устранить дублирование, не превращая родную библиотеку DLL C++ в библиотеку DLL удались?

ответ

15

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

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

Альтернативно #if! __ cplusplus public ... – user7116

+1

Я только что проверил что-то подобное - но файл называется MyEnum.cs. Так что он компилирует C# без каких-либо специальных правил. В моем файле на C++ это работает: #include «MyEnum.cs» –

+0

Удивительно, рад, что у вас это работает! – jjxtra

0

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

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

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

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

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

+0

К сожалению, родные dll не может управляться. –

3

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

+0

Это интересный подход. У этого есть побочный эффект, что иначе неэкранное перечисление становится COM публичным. К сожалению, библиотека C# может не запускаться за все время работы/загрузки из-за несовместимости фреймворка на целевых ОС. –

+0

@sean, вы можете выборочно публиковать определенные enums и другие, не используя ComVisibleAttribute. –

0

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

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

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

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

Успехов,

+1

Мне что-то не хватает ... используйте заголовок на C#? –

4

Спасибо за обмен!

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

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

Remember назвать файл * .cs

Смежные вопросы