"
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 329 天前 via Android
黑魔法:根据编译器模拟结构体内存布局。手动对齐。
|