序列化包含std::string的自定义Struct

Serialize a Custom Struct Containing std::string

本文关键字:自定义 Struct string std 序列化 包含      更新时间:2023-10-16

我希望序列化一个包含std::string到文件的类,并轻松地在Python中加载此数据:

class A {
  public:
    int a;
    char b;
    bool c;
    std::string s1;
    std::string s2;
}

我有一个非常繁忙的线程,它处理a的许多实例。它将有趣的实例添加到一个类中,供不那么繁忙的线程稍后编写。

class Blob {
public:
   char data[1024]
   size_t length;
}
void createBlob(void *data, int length) {
  Blob saved_a;
  saved_a.length = length;
  memcpy(saved_a.data, a, length);
}

然后,低优先级线程异步写入blobs到file:文件。Write (reinterpret_cast (&saved_a.length), sizeof(saved_a.length));文件。写(saved_a saved_a.length);

然后Python读取这些文件,并使用struct库加载数据/句柄端序。

我没有一个很好的方法来存储std::string(部分原因是我不明白std::string的生命周期有什么保证)。日志线程是否能够强制转换saved_a。数据到类型a,然后读取字符串?或者memcpy是否只保存指向可能不再有效的字符串的指针?

复制A结构是不可能的,因为createBlob可以采用许多不同的数据结构(只需要一个void *和一个size)。我愿意牺牲平台独立性,并通过打包计算/测试来确保Python解析器正常工作,但确实需要最小化创建blob的函数的负载,并需要确保它可以创建许多不同数据类型的blob。

如果std::字符串在低优先级记录器到达它们时仍然有效,则可以重铸数据并执行完整复制。否则,在传递给createBlob函数之前,是否有一个轻量级的解决方案来序列化结构(在性能上与做内存相当)?

Memcpy对指针不起作用,因为它复制的是指针,而不是指针的值。所以它对结构体中存储的任何对象或数组都没有帮助。没有简单的方法可以自动做到这一点。但是对于字符串,您可以使用0作为字符串结束标志直接将其字节写入内存。像这样:

class A {
  public:
    int a;
    char b;
    bool c;
    std::string s1;
    std::string s2;
    int length()
    {
       sizeof(a) + sizeof(b) + sizeof(c) + s1.length*sizeof(char) + 1 + s2.length*sizeof(char) + 1;
    }
    void* toByteArray()
    {
        char * res = new char[length()];
        int pos =0 ;
        pos+=writebytes(res, pos, tobytes(a));
        pos+=writebytes(res, pos, tobytes(b));
        pos+=writebytes(res, pos, tobytes(c));
        pos+=writebytes(res, pos, tobytes(s1));//string version should append zero char after string
        pos+=writebytes(res, pos, tobytes(s2));
    }
}

也永远不要使用memcpy复制类,因为它也复制虚表指针,而不仅仅是类中的变量。

不,当然不是。不能使用memcpy()将字符串硬塞到blob中。这里最糟糕的是,由于某些实现中可用的小字符串优化,它实际上可能在某些数据上工作。然后它会神奇地在另一组数据上中断。如果你想让你的东西是二进制序列化的(我个人认为二进制序列化已经过时了),用某种CharArray实现替换类中的字符串,它使用数组作为存储。我个人更喜欢适当的序列化。