共享来自 C#、C++/CLI 和 C++ 的枚举
我有一个由三部分组成的图书馆。首先是本机 C++,它提供实际的功能。其次是 C++ 库的 C++/CLI 包装器/适配器,以简化 C# 到 C++ 的转换。最后,我有一个 C# 库,它通过 C++/CLI 适配器调用 C++ 库。
现在我有两组并行枚举定义,一组存储在 .cs 文件中,另一组存储在 .h 文件中。这带来了双重问题:
- 我有双重维护。我必须始终同步两个文件位置中枚举的更改。
- 两个枚举使用的命名空间应该相同,但查看两组枚举并在它们之间进行转换的 C++/CLI 包装器会引发命名冲突。
现在我不确定诸如此 或 可以解决这两个问题。想法?
I have a library that consists of three parts. First is native C++, which provides the actual functionality. Second is a C++/CLI wrapper/adaptor for the C++ library, to simplify the C# to C++ transition. Finally I have a C# library, which invokes the C++ library through the C++/CLI adaptor.
Right now there I have two sets of parallel enum definitions, one stored in a .cs file and the other in a .h file. This poses a double problem:
- I have dual maintenance. I must always synchronize changes of an enum in both file locations.
- The namespace used by both enums should be identical but the C++/CLI wrapper, which views both sets of enums and translates between them, incurs a naming collision.
Right now I'm not sure a solution such as this or that would solve both problems. Thoughts?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
即使您在本机 C++ 中包含 C# 枚举(如 第一个链接),两个枚举并不“相同”,C++ 枚举只不过是命名整数的列表,而 C# 枚举是从 Enum 派生的。因此,当尝试同时使用 C++/CLI 时,会发生冲突。
一个可能的解决方案是使用预处理器,以便您的 C++/CLI 程序集可以看到不同命名空间中的两个枚举:
在您的 C++/CLI 代码中,进行如下包含:
这使您可以区分这两种枚举
C++/CLI 代码中的
EnumShare::MyEnum
或EnumShareManaged::MyEnum
。编辑:刚刚发现 这篇 SO 帖子 显示了正确的内容在非托管和托管枚举之间进行转换的方式,这肯定也适用于此。例如,在 C++/CLI 中,从托管枚举到非托管枚举的转换可以如下完成:
Even if you include the C# enum in your native C++ (as suggested in your first link), both enums are not "the same", the C++ enum is nothing but a list of named integers, while the C# enum is derived from Enum. As a consequence, you get a collision in C++/CLI when trying to use them both.
A possible solution is to use the preprocessor so that your C++/CLI assembly sees both enums in different namespaces:
In your C++/CLI code, make an inclusion like that:
This gives you the availability to distinguish between those two kind of enums
EnumShare::MyEnum
orEnumShareManaged::MyEnum
in your C++/CLI code.EDIT: just found this SO post showing the correct way to cast between unmanaged and managed enums, this surely will work here, too. For example, in the C++/CLI, the transition from managed to unmanaged enum can be done like this:
考虑编写代码生成器程序,该程序读取带有枚举的本机 h 文件并生成另一个 h 文件,将枚举转换为 C++/CLI 枚举类。此类代码生成器可在自定义构建步骤的 C++/CLI 项目中使用,生成所需的 CLI 枚举。
我使用这种方法生成本机包装类,以获取非托管 C++ 中的 Enum::GetNames 和 Enum::GetName 函数。
Consider writing code generator program, which reads native h-file file with enumerations and generates another h-file, converting enum to C++/CLI enum class. Such code generator can be used in C++/CLI project on the Custom Build Step, producing required CLI enumerations.
I use this approach to generate native wrapper classes to get Enum::GetNames and Enum::GetName functions in unmanaged C++.
只需将
#include "Enum.cs"
指令放入外部命名空间即可解决命名冲突。编辑:Brent 建议的一种变体是使用
#define
替换 .cs 文件中声明的命名空间之一(甚至枚举名称本身)。这也避免了命名冲突,而不会使命名空间层次结构更深。Just put your
#include "Enum.cs"
directive inside an outer namespace to resolve the naming collision.EDIT: A variation suggested by Brent is to use
#define
to substitute one of the namespaces (or even the enum name itself) declared in the .cs file. This also avoids the naming collision, without making the namespace hierarchy deeper.