Совместно используя перечисление от C#, C++ / CLI и C++

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

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

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

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

23
задан Brent Arias 13 July 2010 в 18:34
поделиться

3 ответа

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

РЕДАКТИРОВАТЬ: Брент предлагает вариант использования #define для замены одного из пространств имен (или даже самого имени перечисления), объявленных в файле .cs. Это также позволяет избежать конфликта имен, не углубляя иерархию пространства имен.

2
ответ дан 29 November 2019 в 03:05
поделиться

Даже если вы включите перечисление 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);
}
11
ответ дан 29 November 2019 в 03:05
поделиться

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

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

3
ответ дан 29 November 2019 в 03:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: