"
struct demo
{
uint32_t x;
double y;
int arr[3];
}
"
请问大家,假设有这样的一个字符串,C++有没有现成的库,可以方便地把字符串转成结构体定义呢?
1
star9029 326 天前 1
没理解问题。。是想要反序列化?目前 cpp 没有官方反射,序列化之类的操作都没有完美的方法实现
|
2
venicejack 326 天前 1
用 protobuf 处理,code gen 成你想要的代码,c++是编译型语言,一切类型都需要在编译时确定下来
|
3
iOCZS 326 天前 1
没什么意义,你又用不到它的静态特性,只考虑动态特性,那不就是一个多字段的值的集合么。
|
4
424778940 326 天前 1
考虑 protobuf 或者 json 库吧 但这些也都是要预定义结构的
动态定义的基本没有, 但如果熟悉内存操作也不是不能作死弄一套, 但还是要预定义一套规范/协议才行 |
5
Cu635 326 天前 1
输入的字符串就是结构体语法再加上个双引号?双引号的格式是全都是例子这样的么?
如果是的话,看看能不能采用读入字符串-->去掉双引号-->去掉双引号的字符串输出/保存成文件-->用保存的文件再进行后续操作的思路。当然,具体实现可能要考虑各种情况。 |
9
terryching 326 天前
看看 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 326 天前 1
提供个思路,如果这个活要我干,我就把 lua 搞进去,如果不让把 lua 搞进去。我就用 json 了。
|
12
churchill 326 天前 1
不明来源的二进制文件,即使能动态定义结构体,比如内嵌一个 TinyC 之类的东西,可是还有内存对齐呢,还是走协议的路子吧
|
14
iOCZS 326 天前 1
正常情况下,为了对齐,字段顺序是可能被调整的。我觉得用 JSON 可能更好
|
16
beyondstars 326 天前 1
我觉得你可能需要的是 C++ 模板元编程 (TMP), TMP 允许你做图灵完备的编译期计算。这本是是教程: https://www.amazon.com/C-Templates-Complete-Guide-2nd/dp/0321714121
|
17
ysc3839 326 天前 via Android 1
印象中 libffi 是可以运行时解析的,去搜了一下似乎不行。
继续搜索发现原来是 Python 的 cffi 库支持这么干,解析代码用的是 pycparser 这个项目。 所以要求不高的话可以考虑嵌入 Python 来实现,否则的话还是找找其他解析 C 代码的库吧。 |
18
beyondstars 326 天前 1
你可以参考这个思路哈: 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 326 天前
std::map
|
20
Inn0Vat10n 326 天前
jit
|
21
GeruzoniAnsasu 325 天前 1
|
22
bl4ckoooooH4t 325 天前 1
不用自己开发,010 editor 的 template 已经有这个功能了
|
23
yyang179 325 天前 1
最近刚好做了个类似的功能,提供一个 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 325 天前
这不就是基于流的解析,参考 IM 中长链接协议的制定这种。
|
25
sjkdsfkkfd 325 天前 via Android 1
ImHex 有一个 pattern language 就是干这个的,你可以参考一下 https://github.com/WerWolv/PatternLanguage/
|
26
aloxaf 325 天前 1
Kaitai Struct ?
|
27
neocanable 325 天前
@wisefree 这样假设好实现,hard code 一堆,估计莫名的 bug 会一堆一堆,找的时候痛苦的要死
|
28
yanqiyu 325 天前 via Android
感觉是 jit 的活
|
29
tyzandhr 285 天前 via Android
黑魔法:根据编译器模拟结构体内存布局。手动对齐。
|