我目前正在创建一个新的 C# 项目,该项目需要与旧的 C++ 应用程序进行交互。 C++ 应用程序中已存在一个错误枚举,我需要在 C# 应用程序中使用该错误枚举。
我不想在 C# 中重新声明枚举,因为如果文件没有一起更新,这可能会导致同步问题。
话虽如此,我的问题是: 有没有办法让我采取这样声明的枚举:
typedef enum
{
eDEVICEINT_ERR_FATAL = 0x10001
...
} eDeviceIntErrCodes;
并在 C# 程序中使用它,如下所示:
eDeviceIntErrCodes.eDEVICEINT_ERR_FATAL
在 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++构建环境中不存在这样的预处理器定义。
请注意,这只能确保两个部分在构建时同步。如果您混合搭配来自不同版本的二进制文件,则保证失败。
查看 PInvoke Interop Assistant 工具 https://github.com/jaredpar/pinvoke-interop-assistant。它是为本机方法生成 PInvoke 签名的有用工具。
如果我向它提供你的枚举,它会生成此代码。该工具包含一个命令行版本,因此您可以构建一个自动化流程,以便在 C++ 版本发生更改时保持枚举的 C# 定义保持最新。
public enum eDeviceIntErrCodes
{
/// eDEVICEINT_ERR_FATAL -> 0x10001
eDEVICEINT_ERR_FATAL = 65537,
}
简单的答案是否定的。抱歉,您必须重新声明。
但是,我过去曾编写过脚本,将我的 C++ 枚举导入到 enums.cs 文件中的 C# 格式,并将其作为构建的一部分运行,这样一切都会同步。
如果您在 C++/CLI 中定义强枚举,枚举代码将包含在 dll 元数据中。因此,您可以在 C# 中使用枚举代码。
public enum class eDeviceIntErrCodes: int
{
eDEVICEINT_ERR_FATAL = 0x10001
...
};
如果您已声明枚举:
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;