序列化包含std :: string

时间:2015-08-19 23:14:30

标签: c++ c++11 serialization stdstring

我希望序列化一个包含std :: string to file的类,并在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);
}

然后,低优先级线程将blob异步写入文件:     file.write(reinterpret_cast(& saved_a.length),sizeof(saved_a.length));     file.write(saved_a,saved_a.length);

然后Python读取这些文件并使用struct library加载数据/句柄字节序。

我没有很好的方法来存储std :: string(部分是因为我不明白什么保证了std :: string的生命周期)。日志记录线程是否能够将saved_a.data转换为类型A然后读取字符串?或者memcpy只保存指向可能不再有效的字符串的指针。

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

如果std :: string在低优先级记录器到达时仍然有效,他可以重新创建数据并执行完整拷贝。否则,在传递给createBlob函数之前是否有一个轻量级的解决方案来序列化结构(性能与memcpy相当)?

2 个答案:

答案 0 :(得分:0)

Memcpy永远不会用于指针,因为它复制指针,而不是它们的值。因此,它不会帮助您存储在结构中的任何对象或数组。 没有简单的方法可以自动完成。但对于字符串,您可以使用零作为字符串结束标志直接将其字节写入内存。 像这样:

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复制类,因为它还复制虚拟表指针,而不仅仅是类内的变量。

答案 1 :(得分:0)

不,当然不是。你不能使用memcpy()将字符串塞入blob。这里最糟糕的是,由于某些实现中可用的小字符串优化,它实际上可能对某些数据起作用。而且它将神奇地打破另一组数据。 如果你希望你的东西是二进制可序列化的(我个人觉得二进制序列化已经过时了)用某种CharArray实现替换你的类中的字符串,它使用数组作为存储。 我个人更喜欢正确的序列化。