将 C++ 枚举导入 C#

Posted

技术标签:

【中文标题】将 C++ 枚举导入 C#【英文标题】:Importing C++ enumerations into C# 【发布时间】:2010-09-06 08:01:49 【问题描述】:

我目前正在创建一个需要与旧 C++ 应用程序交互的新 C# 项目。我需要在 C# 应用程序中使用的 C++ 应用程序中已经存在一个错误枚举。

我不想在 C# 中重新声明枚举,因为如果文件没有一起更新,这可能会导致同步问题

话虽如此,我的问题是: 有没有办法让我采用这样声明的枚举:

typedef enum

    eDEVICEINT_ERR_FATAL = 0x10001
    ...
 eDeviceIntErrCodes;

并像这样在 C# 程序中使用它:

eDeviceIntErrCodes.eDEVICEINT_ERR_FATAL

【问题讨论】:

【参考方案1】:

在 C/C++ 中,您可以#include 一个包含枚举定义的 .cs 文件。谨慎使用预处理器指令会处理 C# 和 C 之间的语法差异。

例子:

#if CSharp
namespace MyNamespace.SharedEnumerations

public
#endif


enum MyFirstEnumeration

    Autodetect = -1,
    Windows2000,
    WindowsXP,
    WindowsVista,
    OSX,
    Linux,

    // Count must be last entry - is used to determine number of items in the enum
    Count
;
#if CSharp
public 
#endif

enum MessageLevel

    None,           // Message is ignored
    InfoMessage,    // Message is written to info port.
    InfoWarning,    // Message is written to info port and warning is issued
    Popup           // User is alerted to the message
;

#if CSharp
    public delegate void MessageEventHandler(MessageLevel level, string message);

#endif

在您的 C# 项目中,设置条件编译符号“CSharp”,确保 C/C++ 构建环境中不存在此类预处理器定义。

请注意,这只会确保两个部分在构建时同步。如果您混合和匹配来自不同构建的二进制文件,则保证失败。

【讨论】:

【参考方案2】:

查看 PInvoke Interop Assistant 工具 http://www.codeplex.com/clrinterop/Release/ProjectReleases.aspx?ReleaseId=14120。它是为本地方法生成 PInvoke 签名的有用工具。

如果我将它提供给您的枚举,它会生成此代码。包含该工具的命令行版本,因此您可以构建一个自动化过程,以在 C++ 版本更改时保持枚举的 C# 定义为最新。


    public enum eDeviceIntErrCodes 
    
        /// eDEVICEINT_ERR_FATAL -> 0x10001
        eDEVICEINT_ERR_FATAL = 65537,
    

【讨论】:

【参考方案3】:

简单的答案是否定的。抱歉,您将不得不重新声明。

然而,我过去曾编写脚本将我的 C++ 枚举导入到 enums.cs 文件中的 C# 格式,并将其作为构建的一部分运行,这样一切都会同步。

【讨论】:

【参考方案4】:

如果您已将枚举声明为:

namespace blah

    enum DEVICE_ERR_CODES
    
        eDEVICEINT_ERR_FATAL = 0x10001,
        eDEVICEINT_ERR_OTHER = 0x10002,
    ;

在另一个文件中:

DEVICE_ERR_CODES eDeviceIntErrCodes;

并使用 .cs 扩展名命名枚举文件,您也许可以让它工作。 你会像这样引用它:

DEVICE_ERR_CODES err = DEVICE_ERR_CODES.eDEVICEINT_ERR_FATAL;

【讨论】:

【参考方案5】:

如果您在 C++/CLI 中定义强枚举,则枚举代码将包含在 dll 元数据中。因此,您可以在 C# 中使用枚举代码。

public enum class eDeviceIntErrCodes: int

    eDEVICEINT_ERR_FATAL = 0x10001
    ...
;

【讨论】:

以上是关于将 C++ 枚举导入 C#的主要内容,如果未能解决你的问题,请参考以下文章

如何将托管 c++ 库导入 C# 应用程序(目标 .net 版本 3.5)

如何从 C# 导入和使用非托管 C++ 类?

当我从 C# 代码调用导入的 C++ 函数时,为啥会引发 AccessViolationException?

C++ 如何导入用 C# 制作的 DLL?

C#编组来自C++ DLL的无符号字符返回值[重复]

调试由 C# Visual Studio 2010 插件导入的 C++ dll