C结构(C POD)和Google Protobufs之间的转换

Conversion between C structs (C++ POD) and google protobufs?

本文关键字:Protobufs 之间 转换 Google 结构 POD      更新时间:2023-10-16

我的代码当前通过许多(有时是嵌套)C(或C 普通旧数据)结构和数组。

我想将其转换为Google Protobufs。我可以手动编写在这两种格式之间转换的代码,但是对于自动生成此类代码的错误不容易出错。做这个的最好方式是什么?(用一种具有足够内省的语言来迭代成员变量的名称,这很容易,但这是我们正在谈论的C 代码)

我正在考虑的一件事是编写解析C结构然后吐出.proto文件的Python代码以及所有类型的C代码,该代码将c代码复制到成员(以任一个方向),但也许可以有一种更好的方法...或者也许还有另一个已经可以生成的IDL:

  1. .h文件包含所有嵌套类型
  2. .proto文件包含等效物
  3. .c .c文件,其功能可以在.proto文件生成的C 结构之间复制任一方向和.h文件中定义的结构

我找不到解决这个问题的解决方案,如果有一个问题,请让我知道!

如果您决定在Python中滚动,则GDB的Python绑定可能很有用。然后,您可以读取符号表,找到指定文件中定义的所有结构,然后迭代所有结构成员。然后使用<gdbtype>.strip_typedefs()获取每个成员的原始类型并将其转换为适当的Protobuf类型。

这可能比文本解析器更安全,因为它将处理取决于体系结构,编译器标志,预处理器宏等的类型。

我猜想要转换为Protobuf的代码也可以从结构成员到消息字段关系生成,但听起来并不容易。

可以通过使用TextFormat解析ASCII表示来构建协议缓冲区。因此,一种选择是在每个结构中添加方法dumpAsciiProtoBuf。该方法将转储任何简单的字段(例如字符串,布尔等),并在嵌套结构字段上递归调用dumpAsciiProtoBuf。然后,您必须确保串联结果是有效的ASCII协议缓冲区,可以使用TextFormat进行解析。

请注意,这可能具有一些性能的影响(因为解析ASCII表示可能很昂贵)。但是,这将为您节省用不同语言编写转换器的麻烦,因此它似乎是一个方便的解决方案。

提出的问题是" c&quot"的古老挑战。(和C )代码 - 无需简单(或标准)的方式来反思c&quot struct'(或类)。只需在C反射上搜索堆栈溢出,您就会看到很多失败的尝试。我的第一个建议将不是尝试构建另一个解决方案(在Python等)。

一种简单的方法:考虑使用GDB PTYPE为您获取结构化输出,您可以使用它们来创建.proto文件。优点是无需处理C语言的完整语法(#Define,Line Breaks,...)。查看如何显示结构在GDB中具有哪些字段?

从GDB ptype中,这是protobuf'.proto'文件的短途旅行。

您可以从libclang获得类似的结果(而且我相信有可比的GCC插件,但我无法找到它)。但是,您将不得不写一些非平凡的" c&quot"代码。

另一种方法 - 将是使用'swig'(https://www.swig.org),然后处理swig xml输出(或-XMLOUT选项)将解析树倒入XML中。虽然这种方法需要进行一些挖掘才能找到所需的结构,但XML格式的信息是完整的,易于解析的(使用您想要的任何XML解析器-Python,Perl)。如果您足够勇敢,则可以使用XSLT生成输出。

我不会自己解析C源代码,而是我会使用libclang将C文件解析为AST和我自己的AST Walker来生成Protobuf和Transcoders,并根据需要。谷歌搜索" libclang walk ast"应该从此GitHub存储库中提供一些开始,例如ast-walker.ccast-dumper.cc