c – 浅拷贝到协议缓冲区的字节字段
假设我有一个具有字节字段的proto:
message MyProto { optional bytes data = 1; } 我不能控制的API给我一个指向源数据及其大小的指针.我想让一个MyProto从这个数据中没有深入的复制.我以为这很容易做,但似乎是不可能的. set_data很容易深入复制. Protobuf提供了一个set_allocated_data函数,但是它需要一个指向std :: string的指针,它不能帮助我,因为(除非我被误认为)没有办法使std :: string没有深入复制. void populateProto(void* data,size_t size,MyProto* message) { // Deep copy is fine,I guess. message->set_data(data,size); // Shallow copy would be better... // message->set_allocated_data( ??? ); } 有没有办法正确地填充这个proto(这样可以稍后序列化),而不会将源数据深入复制到字节字段中? 我知道我可以立即手动进行序列化,但如果可能的话我宁愿不做. 解决方法
很好的问题选项是:
>如果您可以更改.proto文件,请考虑实施 message MyProto { bytes data = 1 [ctype = STRING_PIECE]; } 有关实施指南,请参见this discussion.您可以忽略竞技场分配的注释,这不适用于您的情况.值得Google询问ETA. ::str::string* buf = myProto->mutable_data(); buf->reserve(size); api(buf->data(),size); // data is contiguous per c++11 std > NON STANDARD:通过覆盖字符串实例中的数据来打破封装. C有一些精彩的功能,给你足够的绳子来挂自己.这个选项不安全,取决于你的std :: string的执行和其他因素. // NEVER USE THIS IN PRODUCTION void string_jam(::std::string * target,void * buffer,size_t len) { /* On my system,std::string layout * 0: size_t capacity * 8: size_t size * 16: char * data (iff strlen > 22 chars) */ assert(target->size() > 22); size_t * size_ptr = (size_t*)target; size_ptr[0] = len; // Overwrite capacity size_ptr[1] = len; // Overwrite length char ** buf_ptr = (char**)(size_ptr + 2); free(*buf_ptr); // Free the existing buffer *buf_ptr = (char*)buffer; // Jam in our new buffer } 注意:这可能会让你被解雇.这对于测试性能影响是有用的,如果你做了零拷贝路由,但不要在prod中. 如果你选择#1,那么如果你可以释放源代码,那么很多人会受益于这个能力.最好的运气. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |