Совместное использование перечисления из C #, C ++ / CLI и C ++ - PullRequest
23 голосов
/ 13 июля 2010

У меня есть библиотека, которая состоит из трех частей.Во-первых, это родной C ++, который обеспечивает реальную функциональностьВторой - оболочка / адаптер C ++ / CLI для библиотеки C ++, упрощающая переход с C # на C ++.Наконец, у меня есть библиотека C #, которая вызывает библиотеку C ++ через адаптер C ++ / CLI.

Прямо сейчас у меня есть два набора параллельных определений enum, один хранится в файле .cs, а другой - в.ч файл.Это создает двойную проблему:

  1. У меня двойное обслуживание.Я всегда должен синхронизировать изменения перечисления в обоих местоположениях файлов.
  2. Пространство имен, используемое обоими перечислениями, должно быть идентичным, но оболочка C ++ / CLI, которая просматривает оба набора перечислений и осуществляет перевод между ними, вызывает конфликт имен.

Сейчас я не уверен, что решение, такое как , это или , которое решит обе проблемы.Мысли?

Ответы [ 3 ]

11 голосов
/ 13 июля 2010

Даже если вы включите перечисление 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.

РЕДАКТИРОВАТЬ: только что найдено этоТак что пост , показывающий правильный способ приведения между неуправляемыми и управляемыми перечислениями, наверняка сработает и здесь.Например, в C ++ / CLI переход от управляемого к неуправляемому перечислению может быть сделан следующим образом:

void MyWrapperClass::MyWrapperFunction(EnumShareManaged::MyEnum mx)
{
    EnumShare::MyEnum nx = static_cast<EnumShare::MyEnum>(mx);
    // call a native function "func"
    func(nx);
}
3 голосов
/ 14 июля 2010

Рассмотрим написание программы генератора кода, которая считывает собственный файл h-файла с перечислениями и генерирует другой h-файл, преобразуя перечисление в класс перечисления C ++ / CLI. Такой генератор кода можно использовать в проекте C ++ / CLI на шаге пользовательской сборки, создавая необходимые перечисления CLI.

Я использую этот подход для генерации собственных классов-оболочек для получения функций Enum :: GetNames и Enum :: GetName в неуправляемом C ++.

2 голосов
/ 14 июля 2010

Просто поместите директиву #include "Enum.cs" во внешнее пространство имен, чтобы разрешить конфликт имен.

EDIT: вариант, предложенный Brent, заключается в использовании #define для замены одного из пространств имен (или даже самого имени перечисления), объявленных в файле .cs. Это также позволяет избежать конфликта имен, не делая иерархию пространства имен более глубокой.

...