是否可以在 C# 和非托管 C++ 之间共享枚举声明?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/954321/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:09:12  来源:igfitidea点击:

Is it possible to share an enum declaration between C# and unmanaged C++?

c#c++enumsnativemanaged

提问by sean e

Is there a way to share an enum definition between native (unmanaged) C++ and (managed) C#?

有没有办法在本机(非托管)C++ 和(托管)C# 之间共享枚举定义?

I have the following enum used in completely unmanaged code:

我在完全非托管的代码中使用了以下枚举:

enum MyEnum { myVal1, myVal2 };

Our application sometimes uses a managed component. That C# component gets the enum item values as ints via a managed C++ interop dll (from the native dll). (The interop dll only loads if the C# component is needed.) The C# component has duplicated the enum definition:

我们的应用程序有时会使用托管组件。该 C# 组件通过托管的 C++ 互操作 dll(来自本机 dll)获取作为整数的枚举项值。(互操作 dll 仅在需要 C# 组件时才加载。)C# 组件复制了枚举定义:

public enum MyEnum { myVal1, myVal2 };

Is there a way to eliminate the duplication without turning the native C++ dll into a managed dll?

有没有办法在不将本机 C++ dll 转换为托管 dll 的情况下消除重复?

采纳答案by jjxtra

You can use a single .cs file and share it between both projects. #includein C++ on a .cs file should be no problem.

您可以使用单个 .cs 文件并在两个项目之间共享它。#include在 C++ 上一个 .cs 文件应该没问题。

This would be an example .cs file:

这将是一个示例 .cs 文件:

#if !__LINE__    
namespace MyNamespace
{
    public 
#endif

// shared enum for both C, C++ and C#
enum MyEnum { myVal1, myVal2 };

#if !__LINE__
}
#endif

If you want multiple enums in one file, you can do this (although you have to temporarily define public to be nothing for C / C++):

如果你想在一个文件中包含多个枚举,你可以这样做(尽管你必须临时定义 public 为 C/C++ 的空):

#if __LINE__
#define public
#else
namespace MyNamespace
{
#endif

    public enum MyEnum { MyEnumValue1, MyEnumValue2 };
    public enum MyEnum2 { MyEnum2Value1, MyEnum2Value2 };
    public enum MyEnum3 { MyEnum3Value1, MyEnum3Value2 };

#if __LINE__
#undef public
#else
}
#endif

回答by Steffen

Unmanaged C++ and C# live in two different worlds, so no there is no way to use the same enum, without changing the c++ DLL into a managed one.

非托管 C++ 和 C# 存在于两个不同的世界中,因此如果不将 C++ DLL 更改为托管的,就无法使用相同的枚举。

And even then, you'd probably need the duplication in the managed C++ DLL.

即便如此,您也可能需要在托管 C++ DLL 中进行复制。

A C++ enum is much like a list of constants, whereas a C# enum inherits the Enum class, and thus provides quite a few "tricks". So as you can see, they're verydifferent.

C++ 枚举很像一个常量列表,而 C# 枚举继承了 Enum 类,因此提供了很多“技巧”。正如你所看到的,它们是非常不同的。

If it doesn't matter whether the native C++ DLL is native or managed, I'd turn it into a managed one and wrap the native calls inside a managed C++ Layer.

如果本机 C++ DLL 是本机还是托管无关紧要,我会将其转换为托管并将本机调用包装在托管 C++ 层中。

That way you can have the enum duplication inside the C++ DLL, and also you can get rid of all the interop at the same time :-)

这样你就可以在 C++ DLL 中有枚举重复,而且你可以同时摆脱所有的互操作 :-)

回答by sharptooth

You can expose the C# library to COM and then import the type library into the unmanaged code - this way you will be able to use the enum defined in C# library in the unmanaged library.

您可以将 C# 库公开给 COM,然后将类型库导入非托管代码 - 这样您就可以在非托管库中使用 C# 库中定义的枚举。

回答by Adrian Conlon

I've had the same problem in the past and solved it using preprocessor definitions.

我过去遇到过同样的问题,并使用预处理器定义解决了它。

In your unmanaged code, inside a header that can also be included by your managed wrapper, place your enumeration items into a #define.

在您的非托管代码中,在您的托管包装器也可以包含的标头内,将您的枚举项放入 #define 中。

Then, in your managed and unmanaged enumeration definitions, use the same #define for both usages.

然后,在您的托管和非托管枚举定义中,对这两种用法使用相同的 #define。

The movement of the enumerations between the managed and unmanaged world looks slightly nasty (basically a cast is needed), but to your caller in the unmanaged world, it'll look and feel fine.

托管和非托管世界之间的枚举移动看起来有点令人讨厌(基本上需要强制转换),但对于非托管世界中的调用者来说,它看起来和感觉都很好。

Good luck,

祝你好运,

回答by Johan Torp

Thanks for sharing!

感谢分享!

I played around a bit and found a way to have multiple enum and constant declarations without having tons of extra lines :)

我玩了一会儿,找到了一种方法来拥有多个枚举和常量声明而没有大量额外的行:)

// This is a valid C, C++ and C# file :)
#if __LINE__
#define public
#else
namespace MyCSharpNamespace{
#endif

    public enum MyConstant { MaxStr = 256 };
    public enum MyEnum1{ MyEnum1_A, MyEnum1_B };
    public enum MyEnum2{ MyEnum2_A, MyEnum2_B };

#if __LINE__
#undef public
#else
}
#endif

Remember to name your file *.cs

请记住将您的文件命名为 *.cs