簡體   English   中英

C結構(C++ POD)和谷歌protobufs之間的轉換?

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

我的代碼當前傳遞了很多(有時是嵌套的)C(或 C++ 普通舊數據)結構和數組。

我想將這些轉換為/從谷歌 protobufs 轉換。 我可以手動編寫在這兩種格式之間轉換的代碼,但自動生成這樣的代碼不太容易出錯。 做這個的最好方式是什么? (這在具有足夠內省以迭代成員變量名稱的語言中很容易,但這是我們正在談論的 C++ 代碼)

我正在考慮的一件事是編寫解析 C 結構然后輸出 .proto 文件的 python 代碼,以及從成員到成員(在任一方向)復制所有類型的 C 代碼,但也許有一個更好的方法......或者也許已經可以生成另一個 IDL:

  1. .h 文件包含所有嵌套類型
  2. .proto 文件包含等價物
  3. .c 文件,其中包含在 .proto 文件生成的 C++ 結構和 .h 文件中定義的結構之間復制任一方向的函數

可以通過使用TextFormat解析 ASCII 表示來構建協議緩沖區。 因此,一種選擇是將方法dumpAsciiProtoBuf添加到每個結構中。 該方法將轉儲任何簡單字段(如字符串、布爾值等)並在嵌套結構字段上遞歸調用dumpAsciiProtoBuf 然后,您必須確保連接的結果是可以使用TextFormat解析的有效 ASCII 協議緩沖區。

請注意,這可能會對性能產生一些影響(因為解析 ASCII 表示可能很昂貴)。 但是,這樣可以省去用不同語言編寫轉換器的麻煩,所以這似乎是一個方便的解決方案。

我找不到解決此問題的現成解決方案,如果有,請告訴我!

如果您決定在 python 中自己開發,gdb 的 python 綁定可能會很有用。 然后,您可以讀取符號表,查找指定文件中定義的所有結構,並迭代所有結構成員。 然后使用<gdbtype>.strip_typedefs()獲取每個成員的原始類型並將其轉換為適當的 protobuf 類型。

這可能比文本解析器更安全,因為它將處理依賴於架構、編譯器標志、預處理器宏等的類型。

我猜想從 struct 成員到消息字段的關系也可以生成與 protobuf 相互轉換的代碼,但聽起來並不容易。

我不會自己解析 C 源代碼,而是使用LibClang將 C 文件解析為AST和我自己的 AST walker 以根據需要生成Protobuf和轉碼器。 谷歌搜索“libclang walk AST”應該提供一些開始,例如來自這個 github 存儲庫ast-walker.ccast-dumper.cc

提出的問題是“C”(和 C++)代碼的古老挑戰 - 沒有簡單(或標准)的方式來反映 c“結構”(或類)。 只需在 C 反射上搜索堆棧溢出,您就會看到很多不成功的嘗試。 我的第一個建議是不要嘗試構建另一個解決方案(在 python 等中)。

一種簡單的方法:考慮使用 gdb ptype 為您的結構獲取結構化輸出,您可以使用它來創建 .proto 文件。 優點是無需處理 C 語言的完整語法(#define、換行符……)。 請參閱如何顯示結構在 GDB 中具有哪些字段?

從 gdb ptype 到 protobuf '.proto' 文件的短途旅行。

你可以從 libCLang 得到類似的結果(我相信有類似的 gcc 插件,但我找不到它)。 但是,您將不得不編寫一些重要的“C”代碼。

另一種方法 - 將使用“swig”( https://www.swig.org ),並處理 swig xml 輸出(或 -xmlout 選項)以將解析樹轉儲為 XML。 雖然這種方法需要一些挖掘來定位所需的結構,但 XML 格式的信息是完整的,易於解析(使用您想要的任何 XML 解析器 - python、perl)。 如果你足夠勇敢,你可以使用 xslt 來生成輸出。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM