其他分享
首页 > 其他分享> > c-Google协议缓冲区以及将std :: string用于任意二进制数据

c-Google协议缓冲区以及将std :: string用于任意二进制数据

作者:互联网

相关问题:vector <unsigned char> vs string for binary data.

我的代码使用vector< unsigned char>用于任意二进制数据.但是,我的许多代码都必须与Google的协议缓冲区代码交互.协议缓冲区将std :: string用于任意二进制数据.这造成了很多丑陋的分配/复制/空闲周期,只是在Google协议缓冲区和我的代码之间移动数据.在很多情况下,我需要两个构造函数(一个构造函数需要一个向量,一个构造函数需要一个字符串)或两个函数将一个函数转换为二进制有线格式.

该代码在内部处理了很多原始结构,因为结构是内容可寻址的(通过哈希存储和检索),已签名等.因此,这不仅仅是与Google协议缓冲区的接口有关的问题.对象也以原始形式在代码的其他部分处理.

我可以做的一件事就是将我的所有代码剪切成将std :: string用于任意二进制数据.我可以做的另一件事是尝试找出更有效的方法来将向量存储和检索到Google协议缓冲区对象中.我猜我的另一选择是创建标准,简单但缓慢的字符串转换函数并始终使用它们.这样可以避免猖code的代码重复,但是从性能的角度来看将是最糟糕的.

有什么建议么?还有什么更好的选择?

这就是我要避免的事情:

if(SomeCase)
{
    std::vector<unsigned char> rawObject(objectdata().size());
    memcpy(&rawObject.front(), objectdata().data(), objectdata().size());
    DoSometingWith(rawObject);
}

当原始数据已经存在时,分配,复制,处理,释放是完全没有意义的.

解决方法:

有两种避免复制的方法,我知道并已经在使用中.

实际上,传统方式确实是将指针/引用传递给已知实体.尽管这可以很好地工作并且大惊小怪,但问题是,它将您与给定的表示形式联系在一起,这需要在必要时进行转换(根据您的经验).

我用LLVM发现的另一种方法是:

> ArrayRef
> StringRef

这个想法非常简单:都持有一个指向T数组开头的T *和一个指示元素数量的size_t.

神奇的是它们完全隐藏了实际的存储空间,无论是字符串,向量,动态还是静态分配的C数组……都没有关系.呈现的界面是完全统一的,不涉及任何副本.

唯一的警告是,它们不拥有内存的所有权(参考文献!),因此,如果您不小心,可能会潜入一些细微的错误.不过,如果只在瞬态操作中使用它们(例如,在函数内),并且不存储它们以备后用,通常还是可以的.

我发现它们在缓冲区操作中非常方便,尤其是由于有了免费的切片操作.范围比成对的迭代器要容易得多.

我还经历了第三种方法,但是直到现在还没有在严肃的代码中使用过.这个想法是向量< unsigned char>是非常底层的表示.通过提高抽象层并使用Buffer类,您可以完全封装内存的确切存储方式,从而就您的代码而言,它成为非问题.

然后,随意选择一种需要较少转换的内存表示形式.

标签:c,stl,binary-data
来源: https://codeday.me/bug/20191011/1892693.html