从C#,C++/CLI和C++共享枚举

Bre*_*ias 23 .net c# c++ enums c++-cli

我有一个由三部分组成的库.首先是本机C++,它提供实际功能.其次是C++库的C++/CLI包装器/适配器,以简化C#到C++的转换.最后我有一个C#库,它通过C++/CLI适配器调用C++库.

现在我有两组并行枚举定义,一个存储在.cs文件中,另一个存储在.h文件中.这带来了双重问题:

  1. 我有双重维护.我必须始终在两个文件位置同步枚举的更改.
  2. 两个枚举使用的命名空间应该相同,但C++/CLI包装器(它们查看两组枚举并在它们之间进行转换)会引发命名冲突.

现在,我不知道这样的解决这个那个会解决这两个问题.思考?

Doc*_*own 11

即使您在本机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,
    };
}
Run Code Online (Sandbox Code Playgroud)

在您的C++/CLI代码中,包含如下内容:

#undef MANAGED
#include "shared_enum.h"
#define MANAGED
#include "shared_enum.h"
Run Code Online (Sandbox Code Playgroud)

这使您可以区分这两种枚举 EnumShare::MyEnumEnumShareManaged::MyEnumC++/CLI代码.

编辑:刚刚发现这篇SO帖子显示了在非托管和托管枚举之间进行转换的正确方法,这肯定也适用于此.例如,在C++/CLI中,从托管到非托管枚举的转换可以这样完成:

void MyWrapperClass::MyWrapperFunction(EnumShareManaged::MyEnum mx)
{
    EnumShare::MyEnum nx = static_cast<EnumShare::MyEnum>(mx);
    // call a native function "func"
    func(nx);
}
Run Code Online (Sandbox Code Playgroud)


Ben*_*igt 2

只需将#include "Enum.cs"指令放入外部命名空间即可解决命名冲突。

编辑:Brent 建议的一种变体是用来#define替换 .cs 文件中声明的命名空间之一(甚至枚举名称本身)。这也避免了命名冲突,而不会使命名空间层次结构更深。