使用 Cereal 对静态结构数组进行 C++ 序列化

标签 c++ arrays serialization

我正在使用 Cereal 库对结构化数据进行序列化,通过 MPI 发送它们,然后使用 CUDA 在 GPU 上处理它们。由于后者,我不能使用 std::vector,因为 CUDA 在动态对象方面存在问题。因此,我正在使用结构的静态数组。


目标

对具有嵌套静态对象数组的对象进行二进制序列化和反序列化。


要序列化的对象

//==========================================================//
//                  ELEMENT DEFINITION                      //
//==========================================================//
class element{
public:
    //==========================//
    //          CONTENT         //
    //==========================//
    int grid_id;
    int NN_id;
    int debug;

    //==========================//
    //      SERIALIZATION       //
    //==========================//
    // function required by cereal library
    template<class Archive>
    void serialize(Archive & ar){
        ar( grid_id );
        ar( NN_id );
        ar( debug );
    }
};

//==========================================================//
//                      CONTAINER DEFINITION                //
//==========================================================//
class GPU_in_grid : public Managed{
public:
    //==========================//
    //          CONTENT         //
    //==========================//
    int gpu_id;
    element element[GRID_SIZE];        <------ static array of structures
    int debug;


    //==========================//
    //      SERIALIZATION       //
    //==========================//
    template<class Archive>
    void serialize(Archive & ar){
        ar( gpu_id );
        ar( debug );
        ar( element );

    }
};

序列化函数

// cereal serialization
#include <cereal/archives/binary.hpp>
#include <cereal/archives/portable_binary.hpp>
//#include <cereal/archives/xml.hpp>

template<typename data_type>
int Process::serialize(data_type * data, char *serial_data, int *size){
    // serialize the data
    std::ostringstream oss(std::ios::binary);
    cereal::BinaryOutputArchive ar(oss);
    //cereal::XMLOutputArchive ar(std::cout);
    ar(*data);
    std::string s=oss.str();
    *size = s.length();
    strncpy(serial_data, s.c_str(), s.length());
    std::cout << "buffer["<< s.length() << "] >> " << s << std::endl;
    s.clear();
    return _SUCCESS_;
};

template<typename data_type>
int Process::deserialize(data_type * data, char *serial_data, int size){
    // create temporary buffer to store the received data
    char * buf=new char[size];
    strncpy(buf, serial_data, size);
    std::istringstream iss(std::string(serial_data, size), std::ios::binary);
    cereal::BinaryInputArchive arin(iss);
    arin(*data);
    // clean buffer
    delete[] buf;
    return _SUCCESS_;
};

调试输出

cpu_mem BEFORE serialization
    cpu_mem.debug = -1
    cpu_mem.gpu_id = -5
    cpu_mem.element[0].NN_id = 1  
    cpu_mem.element[0].debug = 2  
buffer[248] >> ��������           <------ binary format
cpu_mem AFTER deserialization
    cpu_mem.debug = -1            <----- CORRECT
    cpu_mem.gpu_id = -5           <----- CORRECT
    cpu_mem.element[0].NN_id = 0  <----- INCORRECT
    cpu_mem.element[0].debug = 0  <----- INCORRECT

如果我尝试一下流,我可以将序列化的对象打印为 XML,以检查序列化是否成功。

<?xml version="1.0" encoding="utf-8"?>
<cereal>
    <value0>
        <gpu_id>-5</gpu_id>               <----- CORRECT
        <debug>-1</debug>                 <----- CORRECT
        <element>
            <value0>
                <grid_id>0</grid_id>
                <NN_id>1</NN_id>          <----- CORRECT
                <debug>2</debug>          <----- CORRECT
            </value0>
            <value1>
                <grid_id>32522</grid_id>
                <NN_id>2</NN_id>
                <debug>4612412</debug>
            </value1>
        </element>
    </value0>
</cereal>

问题

上面的输出显示,反序列化正确识别容器(类 GPU_in_grid)中的变量,但无法反序列化我的结构的较低级别,即结构静态数组 -> element[]。

最佳答案

由于某些我不知道的原因,strncpy() 出现故障。字符串的内容与数组的内容不同,即使我关注“\0”,也需要将其附加到 char 数组的末尾,此处显示 http://www.cplusplus.com/reference/string/string/copy/ .

我最终改用了 std::string.copy(),只要您在 char 数组末尾添加 '\0',它就会按预期执行。

上面的代码可以正常工作。

关于使用 Cereal 对静态结构数组进行 C++ 序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47574784/

相关文章:

c++ - OpenGL:程序渲染纯白色正方形而不是变换后的正方形

c++ - 为什么 Eclipse 找不到 g++?

c++ - 将父类(super class)传入/传出方法时如何防止自动向下转型

Java 排列赋值

c++ - 分配给指向 std::list 类型的共享指针不起作用

c++ - 如何为 OpenNI2 构建 PCL?

java - 使用多维数组以不同的顺序打印值

javascript - 如果 api 返回 null 数组,则删除子元素

json - JacksonPolymorphicDeserialization : JsonMappingException

java - Jackson:如何在不修改 POJO 的情况下向 JSON 添加自定义属性