在构建时将 C++ 结构转换为 C# 结构

Posted

技术标签:

【中文标题】在构建时将 C++ 结构转换为 C# 结构【英文标题】:converting C++ structure to C# structure at build time 【发布时间】:2013-10-02 13:05:30 【问题描述】:

所以这是背景: 我们有一个用 C++ 编写数据日志的遗留程序。数据包含在不同的结构中。读取日志文件的程序使用这些相同的结构来显示数据。我重写了读取日志文件和 C# 的程序,并且必须手动创建所有这些结构的 C# 副本。 有一个更好的方法吗?我考虑过设置结构的查找路径和一种在构建时生成 C# 结构的解析器,但处理所有特殊情况似乎过于复杂。有什么建议吗? C# 没有任何向后兼容性来处理 C/C++ 结构,这似乎有点荒谬。

【问题讨论】:

【参考方案1】:

有多少结构,它们有多复杂?

我会说这是一个成本与收益的问题。我敢打赌,从你的问题来看,用 C# 快速编码结构是最好的方法。

税前只有我的 2 美分...

【讨论】:

结构比我想的要多。有很多。问题是,如果开发人员更改了 C++ 结构,那么他们必须更改 C# 结构。如果他们不这样做,那么我们只是默认显示十六进制数据。如果碰巧是一条不经常使用的消息,那么我们可能要等到软件发布很久之后才能知道。 如果这是一个内部项目,您当然可以与开发团队协调,在他们更改结构时为您提供 C# 版本...【参考方案2】:

您的问题总结: 您在序列化到磁盘的现有 C++ 程序中有大量结构。您希望将结构移植到 C#,以便可以将磁盘中的数据反序列化到 C# 程序中。你不想只做一次。随着两个程序的发展,您希望这两组结构保持同步。

您需要的是Interface Definition Language (IDL),您可以在其中以独立于语言的方式描述您的数据。类似Apache Thrift、Google Protocol Buffers 或MessagePack。

您必须采取的步骤是:

    将现有的 C++ 结构转换为 IDL。这是一个一次性的过程。使用自定义脚本或查找现有脚本。现在一定有人解决了这个问题。 设置您的构建系统以在构建时生成 C# 和 C++ 定义。 使用 Thrift/ProtoBuf/MessagePack C# 和 C++ API 根据需要对数据进行序列化和反序列化。

缺点是:

    您需要生成构建时代码。但是您自己已经考虑过这一点,并且这样的工作已经为您完成了。 您必须同时更改 C++ 和 C# 才能正确使用为您生成的任何数据结构。 磁盘上的二进制格式将发生变化,因此旧日志将无法读取。但是您可以编写一些 C++ 来轻松地将它们转换为新格式。

我认为这被优势所抵消:

    IDL 将包含数据的规范描述。对它的任何更改都将反映在您的 C++ 和 C# 中。当 C++ 版本发生变化时,您无需手动更新 C# 版本。 二进制数据格式将与机器无关。您将能够在各种平台上以多种不同语言读取/写入数据。 我提到的第三方库功能强大且应用广泛。比自己破解一些东西要好。

【讨论】:

以上是关于在构建时将 C++ 结构转换为 C# 结构的主要内容,如果未能解决你的问题,请参考以下文章

如何将带有 Union 的 C++ 结构转换为 C#?

C++ 从数组转换为结构并转换为 C#

将 C++ 结构转换为 C# 以用于 UDP 通信

将结构列表从 c# 转换为 c++

帮我把 C++ 结构转换成 C#

将包含结构的 c++ 函数传递给 C#,并使用 Marshal.PtrToStructure 将其转换为 c# 函数