У меня есть библиотека, которая состоит из трех частей. Сначала собственный C++, который обеспечивает фактическую функциональность. Второй C++ / обертка/адаптер CLI для библиотеки C++, для упрощения C# до перехода C++. Наконец у меня есть библиотека C#, которая вызывает библиотеку C++ через C++ / адаптер CLI.
Прямо сейчас там у меня есть два набора параллельных перечислимых определений, один сохраненный в .cs файле и другой в.h файле. Это создает двойную проблему:
Прямо сейчас я не уверен решение, такое как это, или это решило бы обе проблемы. Мысли?
Просто поместите директиву #include "Enum.cs"
во внешнее пространство имен, чтобы разрешить конфликт имен.
РЕДАКТИРОВАТЬ: Брент предлагает вариант использования #define
для замены одного из пространств имен (или даже самого имени перечисления), объявленных в файле .cs. Это также позволяет избежать конфликта имен, не углубляя иерархию пространства имен.
Даже если вы включите перечисление C# в ваш родной C++ (как предлагается в вашей первой ссылке), оба перечисления не являются "одним и тем же", перечисление C++ - это не что иное, как список именованных целых чисел, в то время как перечисление C# является производным от Enum. Как следствие, в C++/CLI возникает коллизия при попытке использовать их оба.
Возможным решением является использование препроцессора, чтобы ваша сборка C++/CLI видела оба перечисления в разных пространствах имен:
// shared_enum.h
#undef ENUMKEYWORD
#undef ENUMNAMESPACE
#ifdef MANAGED
#define ENUMKEYWORD public enum class
#define ENUMNAMESPACE EnumShareManaged
#else
#define ENUMKEYWORD enum
#define ENUMNAMESPACE EnumShare
#endif
namespace ENUMNAMESPACE
{
ENUMKEYWORD MyEnum
{
a = 1,
b = 2,
c = 3,
};
}
В вашем коде C++/CLI сделайте включение, подобное этому:
#undef MANAGED
#include "shared_enum.h"
#define MANAGED
#include "shared_enum.h"
Это даст вам возможность различать эти два вида перечислений
EnumShare::MyEnum
или EnumShareManaged::MyEnum
в вашем C++/CLI коде.
EDIT: только что нашел этот пост SO, показывающий правильный способ приведения между неуправляемыми и управляемыми перечислениями, это, несомненно, будет работать и здесь. Например, в C++/CLI переход от управляемого к неуправляемому перечислению можно сделать так:
void MyWrapperClass::MyWrapperFunction(EnumShareManaged::MyEnum mx)
{
EnumShare::MyEnum nx = static_cast<EnumShare::MyEnum>(mx);
// call a native function "func"
func(nx);
}
Рассмотрите возможность написания программы-генератора кода, которая считывает собственный файл h-файла с перечислениями и генерирует другой h-файл, преобразуя перечисление в класс перечисления C ++ / CLI. Такой генератор кода можно использовать в проекте C ++ / CLI на этапе Custom Build, создавая необходимые перечисления CLI.
Я использую этот подход для создания собственных классов-оболочек для получения функций Enum :: GetNames и Enum :: GetName в неуправляемом C ++.