我希望序列化一个包含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相当)?
答案 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实现替换你的类中的字符串,它使用数组作为存储。 我个人更喜欢正确的序列化。