" struct demo { uint32_t x; double y; int arr[3]; } "
请问大家,假设有这样的一个字符串,C++有没有现成的库,可以方便地把字符串转成结构体定义呢?
1 star9029 2024-02-08 20:30:14 +08:00 ![]() 没理解问题。。是想要反序列化?目前 cpp 没有官方反射,序列化之类的操作都没有完美的方法实现 |
![]() | 2 venicejack 2024-02-08 20:30:27 +08:00 ![]() 用 protobuf 处理,code gen 成你想要的代码,c++是编译型语言,一切类型都需要在编译时确定下来 |
3 iOCZS 2024-02-08 20:39:10 +08:00 ![]() 没什么意义,你又用不到它的静态特性,只考虑动态特性,那不就是一个多字段的值的集合么。 |
![]() | 4 424778940 2024-02-08 21:40:31 +08:00 ![]() 考虑 protobuf 或者 json 库吧 但这些也都是要预定义结构的 动态定义的基本没有, 但如果熟悉内存操作也不是不能作死弄一套, 但还是要预定义一套规范/协议才行 |
![]() | 5 Cu635 2024-02-08 21:47:01 +08:00 ![]() 输入的字符串就是结构体语法再加上个双引号?双引号的格式是全都是例子这样的么? 如果是的话,看看能不能采用读入字符串-->去掉双引号-->去掉双引号的字符串输出/保存成文件-->用保存的文件再进行后续操作的思路。当然,具体实现可能要考虑各种情况。 |
![]() | 6 wisefree OP @star9029 我想开发一个二进制数据解析软件,用户输入结构体定义的字符串和二进制文件,我就可以把二进制解析出文本 |
9 terryching 2024-02-08 22:02:38 +08:00 看看 GPT4 给出的答案: 运行时解析:使用已有的数据结构,如 std::map 或自定义的数据结构,来在运行时模拟结构体。基于解析得到的信息(字段名、类型、数组大小等),你可以动态地存储和访问数据。这种方法牺牲了类型安全和编译时优化,但提供了灵活性。 ```c++ #include <iostream> #include <map> #include <vector> #include <string> #include <typeinfo> #include <cstdint> class DynamicStruct { public: std::map<std::string, std::vector<uint8_t>> fields; void addInt(const std::string& name, int value) { auto data = reinterpret_cast<uint8_t*>(&value); fields[name] = std::vector<uint8_t>(data, data + sizeof(value)); } void addDouble(const std::string& name, double value) { auto data = reinterpret_cast<uint8_t*>(&value); fields[name] = std::vector<uint8_t>(data, data + sizeof(value)); } int getInt(const std::string& name) { if(fields.find(name) != fields.end()) { auto& data = fields[name]; return *reinterpret_cast<const int*>(data.data()); } return 0; // Or throw an exception } double getDouble(const std::string& name) { if(fields.find(name) != fields.end()) { auto& data = fields[name]; return *reinterpret_cast<const double*>(data.data()); } return 0.0; // Or throw an exception } // Similar methods can be added for other types and arrays }; int main() { DynamicStruct myStruct; myStruct.addInt("x", 123); myStruct.addDouble("y", 456.789); // For arrays, you might add them element by element or as a block if you know the size std::cout << "x = " << myStruct.getInt("x") << std::endl; std::cout << "y = " << myStruct.getDouble("y") << std::endl; // Accessing array elements would require additional methods return 0; } ``` |
![]() | 11 neocanable 2024-02-08 22:09:26 +08:00 ![]() 提供个思路,如果这个活要我干,我就把 lua 搞进去,如果不让把 lua 搞进去。我就用 json 了。 |
![]() | 12 churchill 2024-02-08 22:11:33 +08:00 ![]() 不明来源的二进制文件,即使能动态定义结构体,比如内嵌一个 TinyC 之类的东西,可是还有内存对齐呢,还是走协议的路子吧 |
14 iOCZS 2024-02-08 22:14:53 +08:00 ![]() 正常情况下,为了对齐,字段顺序是可能被调整的。我觉得用 JSON 可能更好 |
![]() | 16 beyondstars 2024-02-08 22:34:25 +08:00 ![]() 我觉得你可能需要的是 C++ 模板元编程 (TMP), TMP 允许你做图灵完备的编译期计算。这本是是教程: https://www.amazon.com/C-Templates-Complete-Guide-2nd/dp/0321714121 |
![]() | 17 ysc3839 2024-02-08 22:34:50 +08:00 via Android ![]() 印象中 libffi 是可以运行时解析的,去搜了一下似乎不行。 继续搜索发现原来是 Python 的 cffi 库支持这么干,解析代码用的是 pycparser 这个项目。 所以要求不高的话可以考虑嵌入 Python 来实现,否则的话还是找找其他解析 C 代码的库吧。 |
![]() | 18 beyondstars 2024-02-08 22:57:41 +08:00 ![]() 你可以参考这个思路哈: https://studiofuga.com/2016/03/07/a-compact-csv-parser-using-c-tmp/ 这个作者实现了一个编译期的 csv parser, 你也可以做一个编译期的 tokenizer, 然后做 parser, 然后做 synthesizer 只不过 target 就是 类型对象, 最终的效果可能类似于 `my_compiletime_parser<"{ int x; }">::type x;` 等价于 `struct {int x; } x;`. |
19 realJamespond 2024-02-08 23:35:17 +08:00 std::map |
20 Inn0Vat10n 2024-02-09 00:11:02 +08:00 jit |
21 GeruzoniAnsasu 2024-02-09 02:19:16 +08:00 ![]() |
22 bl4ckoooooH4t 2024-02-09 09:52:06 +08:00 ![]() 不用自己开发,010 editor 的 template 已经有这个功能了 |
![]() | 23 yyang179 2024-02-09 11:15:06 +08:00 ![]() 最近刚好做了个类似的功能,提供一个 C++能嵌入 python 的思路: 1. 结构体转 Python ,依托于 ctypeslib2 (这个库通过 clang 的词法分析,将结构体转为 python 的 ctypes ),ctypeslib2 调用 clang 会有些问题,会需要改写 ctypeslib2 的部分源码。 2. Python 可以通过转出的库,用 from_buffer_copy 函数直接做结构体与数据映射(前提是指针长度,对齐方式需要一致),然后导出想要的数据结构,这一步用 python 写起来比 C++方便很多很多。 3. C++调用 python 的脚本,或者通过 pybind11 调用 python 的函数 |
24 gaifanking 2024-02-09 13:10:12 +08:00 这不就是基于流的解析,参考 IM 中长链接协议的制定这种。 |
25 sjkdsfkkfd 2024-02-09 13:44:20 +08:00 via Android ![]() ImHex 有一个 pattern language 就是干这个的,你可以参考一下 https://github.com/WerWolv/PatternLanguage/ |
26 aloxaf 2024-02-09 15:14:59 +08:00 ![]() Kaitai Struct ? |
![]() | 27 neocanable 2024-02-09 21:46:36 +08:00 @wisefree 这样假设好实现,hard code 一堆,估计莫名的 bug 会一堆一堆,找的时候痛苦的要死 |
28 yanqiyu 2024-02-09 22:40:11 +08:00 via Android 感觉是 jit 的活 |
![]() | 29 tyzandhr 2024-03-20 11:29:03 +08:00 via Android 黑魔法:根据编译器模拟结构体内存布局。手动对齐。 |