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

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

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

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

现在我不确定这样或那样的解决方案可以解决这两个问题。 思考?

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

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

即使您在本机C ++中包含C#enum(如第一个链接中所示 ),两个枚举都不是“相同”,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" 

这使您EnumShareManaged::MyEnum在C ++ / CLI代码中区分这两种枚举EnumShare::MyEnumEnumShareManaged::MyEnum

编辑:刚刚发现这个SOpost显示了在非托管和托管枚举之间进行转换的正确方法,这肯定也会在这里工作。 例如,在C ++ / CLI中,从托管到非托管枚举的转换可以这样完成:

 void MyWrapperClass::MyWrapperFunction(EnumShareManaged::MyEnum mx) { EnumShare::MyEnum nx = static_cast(mx); // call a native function "func" func(nx); } 

考虑编写代码生成器程序,该程序使用枚举读取本机h文件文件并生成另一个h文件,将枚举转换为C ++ / CLI枚举类。 此类代码生成器可用于Custom Build Step上的C ++ / CLI项目,从而生成所需的CLI枚举。

我使用这种方法生成本机包装类,以便在非托管C ++中获取Enum :: GetNames和Enum :: GetName函数。