C结构(C POD)和Google Protobufs之间的转换
Conversion between C structs (C++ POD) and google protobufs?
我的代码当前通过许多(有时是嵌套)C(或C 普通旧数据)结构和数组。
我想将其转换为Google Protobufs。我可以手动编写在这两种格式之间转换的代码,但是对于自动生成此类代码的错误不容易出错。做这个的最好方式是什么?(用一种具有足够内省的语言来迭代成员变量的名称,这很容易,但这是我们正在谈论的C 代码)
我正在考虑的一件事是编写解析C结构然后吐出.proto文件的Python代码以及所有类型的C代码,该代码将c代码复制到成员(以任一个方向),但也许可以有一种更好的方法...或者也许还有另一个已经可以生成的IDL:
- .h文件包含所有嵌套类型
- .proto文件包含等效物
- .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.cc
和ast-dumper.cc
。
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- int(c) 和 c-'0' 之间的区别。C++
- 在cuda线程之间共享大量常量数据
- 在c代码之间共享数据的最佳方式
- Mix_Init和Mix_OpenAudio SDL之间的区别是什么
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- std::atomic和std::condition_variable wait,notify_*方法之间的区别
- 大小相等但成员数量不同的结构之间的性能差异
- 类与私有变量的其他类之间的线程安全性
- 如何在cpp文件之间切换窗口?在Qt中
- 线程之间的布尔停止信号
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 在 const 函数中通过引用和指针返回之间的区别
- 我想知道长双倍和双倍之间的区别
- 如何防止clang格式在流运算符调用之间添加换行符<<
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 构造函数和转换运算符之间的重载解析
- C结构(C POD)和Google Protobufs之间的转换