V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
bfjm
V2EX  ›  C++

c++11 怎么序列化结构体?

  •  
  •   bfjm · 2023-02-21 19:53:02 +08:00 via iPhone · 2910 次点击
    这是一个创建于 675 天前的主题,其中的信息可能已经有所发展或是发生改变。
    怎么在编译期知道结构体有哪些成员对象
    23 条回复    2023-03-26 21:14:45 +08:00
    ugpu
        1
    ugpu  
       2023-02-21 19:56:30 +08:00
    auto ptr = &struct
    send_buff(&ptr, len(struct))

    ???? 类似这样 最基础的
    bfjm
        2
    bfjm  
    OP
       2023-02-21 19:59:55 +08:00 via iPhone
    @ugpu 怎么在编译期知道有哪些成员呢
    ysc3839
        3
    ysc3839  
       2023-02-21 20:00:50 +08:00 via Android
    @bfjm 标准 C++没办法
    bfjm
        4
    bfjm  
    OP
       2023-02-21 20:02:58 +08:00 via iPhone
    @ysc3839 有文档讲怎么实现的也可以
    bfjm
        5
    bfjm  
    OP
       2023-02-21 20:03:36 +08:00 via iPhone
    @ysc3839 我找了几个标准都要 14 17 这种满办法满足
    ugpu
        6
    ugpu  
       2023-02-21 20:04:02 +08:00
    @bfjm 编译期知道有哪些成员?
    那就需要自己做结构体特殊化 标识 了吧 纯使用标准库来说 没见到过.
    bfjm
        7
    bfjm  
    OP
       2023-02-21 20:11:08 +08:00 via iPhone
    有 protobuf 可以用 我在知乎上看评论 protobuf 可以实现反射 有人指路一下吗 具体一点
    polythene
        8
    polythene  
       2023-02-21 20:14:51 +08:00
    编译期反射 14/17 都不支持吧,pb 能做到是因为它能从 IDL 文件里拿到字段的偏移量,而不是靠编译期反射吧
    Jiavwen
        9
    Jiavwen  
       2023-02-21 22:26:57 +08:00
    必然有个元数据记录 struct 中每个元素的首地址和偏移量啊
    boboliu
        10
    boboliu  
       2023-02-21 22:38:46 +08:00
    pb 是自己 IDL + codegen 来的
    你要反射的话就只能自己组织元数据了,比如 https://github.com/netcan/recipes/blob/master/cpp/metaproggramming/reflection/StaticRefl.cpp
    kevinlq
        11
    kevinlq  
       2023-02-21 22:53:21 +08:00
    建议先学习第三方库如何使用、再研究如何实现的,最后如果想自己造轮子再试着撸一个。

    可以看看 protobuf ,msgpack 啊这些, 也可以看看 Qt 的元对象实现
    GeruzoniAnsasu
        12
    GeruzoniAnsasu  
       2023-02-21 23:31:56 +08:00
    啊? 序列化结构体

    boost::serialization
    mingl0280
        13
    mingl0280  
       2023-02-22 04:00:42 +08:00 via Android
    结构体是 POD 的:头文件直接转 char 或者 unsigned char 。
    非 POD 的:头文件+序列化 /反序列化函数
    mingl0280
        14
    mingl0280  
       2023-02-22 04:02:00 +08:00 via Android
    要获取成员涉及到一些模板元编程的东西,你现在没必要研究这个
    786375312123
        15
    786375312123  
       2023-02-22 04:51:37 +08:00
    编译期知道结构体有哪些成员对象?
    太难了,你连编译期间 enum 里有那些成员都没法弄清楚,还需要写一个标记开头结尾。
    就这么看编译期间想知道类里有什么根本做不到,除非这个类是模板类?模板类能做到么?我没试过。
    xy629
        16
    xy629  
       2023-02-22 05:48:05 +08:00
    #include <iostream>
    #include <fstream>
    #include <sstream>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <stdexcept>

    #include <boost/archive/text_iarchive.hpp>
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/binary_iarchive.hpp>
    #include <boost/archive/binary_oarchive.hpp>

    struct MyStruct
    {
    int i;
    double d;
    std::string s;

    // 序列化成文本格式
    template <class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
    ar & i;
    ar & d;
    ar & s;
    }
    };

    int main()
    {
    // 将结构体序列化为二进制格式并写入文件
    {
    MyStruct s{42, 3.14, "hello world"};
    std::ofstream ofs("data.bin", std::ios::binary);
    boost::archive::binary_oarchive oa(ofs);
    oa << s;
    }

    // 从文件中读取二进制数据并反序列化为结构体
    {
    MyStruct s;
    std::ifstream ifs("data.bin", std::ios::binary);
    boost::archive::binary_iarchive ia(ifs);
    ia >> s;

    // 验证反序列化结果是否正确
    if (s.i != 42 || s.d != 3.14 || s.s != "hello world")
    {
    throw std::runtime_error("Deserialization failed");
    }
    }

    return 0;
    }
    AlohaV2
        17
    AlohaV2  
       2023-02-22 08:49:19 +08:00
    感觉可以看一下 protobuf
    blinue
        18
    blinue  
       2023-02-22 08:55:53 +08:00
    不追求安全性的话可以看一下 https://github.com/niXman/yas
    最大的优点是唯头文件,速度也很快。
    bfjm
        19
    bfjm  
    OP
       2023-02-23 23:08:51 +08:00
    用 boost 的序列化库解决了
    bfjm
        20
    bfjm  
    OP
       2023-02-23 23:09:45 +08:00
    @xy629 thank you ,我最后也是差不多这种
    alqaz
        21
    alqaz  
       2023-03-01 21:11:34 +08:00
    可以试试 iguana
    tyzandhr
        22
    tyzandhr  
       2023-03-24 06:28:06 +08:00 via Android
    @bfjm pfr 吗?这个库貌似使用结构化绑定做的,似乎不能超过 20 个成员变量
    bfjm
        23
    bfjm  
    OP
       2023-03-26 21:14:45 +08:00
    @tyzandhr boost 的 serialize 库,手动写一个 serialize 函数就好了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2828 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 14:08 · PVG 22:08 · LAX 06:08 · JFK 09:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.