为什么我的protobuf反序列化给空负载? 在VS2017上运行Windows的原版本3.90,我尝试用C++中的代码> > CODIDOutOutsFux和 CordEndoStuts在我的C++中进行序列化和反序列化,但是解码器总是给我一个空的结果。我使用长度前缀,可以从解码器端的流中读取大小。就地编码/解码源代码如下所示,其中使用Any消息 导入“google/protobuf/any.proto”; 信息袋{ google.protobuf.Any msg=1; } bool编码解码(google::protobuf::Message*pMeta,std::string&out_数据包){ // //编码 // //警告: //-必须动态分配以避免protobuf错误。 std::shared_ptr pPayload=std::make_shared(); 谷歌::protobuf::任何环境; 环境包装材料(*pMeta); pPayload->设置\分配\消息(&env); //带大小的前缀 常数int n字节=4; int nBytesMsg=(int)pMeta->ByteSizeLong(); int nBytesPacket=nBytesMsg+n字节; out_packet.assign(nBytesPacket,'\0'); google::protobuf::io::ArrayOutputStream aos((void*)out_packet.c_str(),nBytesPacket); google::protobuf::io::CodedOutputStream cos(&aos); cos.WriteVarint32(NBYTESSG); bool res=pMeta->SerializeToCodedStream(&cos); printf(“有效负载有消息:%d\n”,pPayload->has_msg()); // //解码 // 袋出袋; google::protobuf::io::ArrayInputStream ais(out_packet.c_str(),nBytesPacket); google::protobuf::io::CodedInputStream CI(&ais); google::protobuf::uint32 NPayolad字节; cis.ReadVarint32(&npayoladbytes); google::protobuf::io::CodedInputStream::Limit msgLimit=cis.PushLimit(nPayloadBytes); res=out_pocket.ParseFromCodedStream(&cis); cis.PopLimit(msgLimit); printf(“解码的有效负载有消息:%d\n”,out_pocket.has_msg()); pPayload->release_msg(); 返回res; }

为什么我的protobuf反序列化给空负载? 在VS2017上运行Windows的原版本3.90,我尝试用C++中的代码> > CODIDOutOutsFux和 CordEndoStuts在我的C++中进行序列化和反序列化,但是解码器总是给我一个空的结果。我使用长度前缀,可以从解码器端的流中读取大小。就地编码/解码源代码如下所示,其中使用Any消息 导入“google/protobuf/any.proto”; 信息袋{ google.protobuf.Any msg=1; } bool编码解码(google::protobuf::Message*pMeta,std::string&out_数据包){ // //编码 // //警告: //-必须动态分配以避免protobuf错误。 std::shared_ptr pPayload=std::make_shared(); 谷歌::protobuf::任何环境; 环境包装材料(*pMeta); pPayload->设置\分配\消息(&env); //带大小的前缀 常数int n字节=4; int nBytesMsg=(int)pMeta->ByteSizeLong(); int nBytesPacket=nBytesMsg+n字节; out_packet.assign(nBytesPacket,'\0'); google::protobuf::io::ArrayOutputStream aos((void*)out_packet.c_str(),nBytesPacket); google::protobuf::io::CodedOutputStream cos(&aos); cos.WriteVarint32(NBYTESSG); bool res=pMeta->SerializeToCodedStream(&cos); printf(“有效负载有消息:%d\n”,pPayload->has_msg()); // //解码 // 袋出袋; google::protobuf::io::ArrayInputStream ais(out_packet.c_str(),nBytesPacket); google::protobuf::io::CodedInputStream CI(&ais); google::protobuf::uint32 NPayolad字节; cis.ReadVarint32(&npayoladbytes); google::protobuf::io::CodedInputStream::Limit msgLimit=cis.PushLimit(nPayloadBytes); res=out_pocket.ParseFromCodedStream(&cis); cis.PopLimit(msgLimit); printf(“解码的有效负载有消息:%d\n”,out_pocket.has_msg()); pPayload->release_msg(); 返回res; },c++,protocol-buffers,C++,Protocol Buffers,上面的代码打印出一个空类型的URL payload has message: 1 decoded payload has message: 0 但是大小前缀npayoladbytes给出了正确的数字。 编码和解码的结果都是true 我错在哪里?编码时,您正在将任何类型的pMeta包写入CODEDOUTPTSTREAM cos,解码时需要一个消息包。 我认为您的意思是对pPayload消息进行编码,而不是对pMeta消息进行编码,pMeta消息已经包含在它的msg字段中。 用于测试的完整代码:

上面的代码打印出一个空类型的URL

payload has message: 1
decoded payload has message: 0
但是大小前缀
npayoladbytes
给出了正确的数字。 编码和解码的结果都是
true


我错在哪里?

编码时,您正在将任何类型的pMeta包写入CODEDOUTPTSTREAM cos,解码时需要一个消息包。 我认为您的意思是对pPayload消息进行编码,而不是对pMeta消息进行编码,pMeta消息已经包含在它的msg字段中。 用于测试的完整代码:

#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/util/delimited_message_util.h>
#include "teste.pb.h"

#include <string>

bool EncodeDecode(google::protobuf::Message* pMeta, std::string& out_packet) {  
    //
    // Encoding
    //
    // CAUTION:
    // - Must dynamic allocate to avoid protobuf bug <SharedDtor crash #435>.
    std::shared_ptr<Pouch> pPayload = std::make_shared<Pouch>();
    google::protobuf::Any env;
    env.PackFrom(*pMeta, "bob.bob.bob");
    pPayload->set_allocated_msg(&env);  
    // Prefix with size
    const int nTipBytes = 4;
    int nBytesMsg = (int)pPayload->ByteSizeLong();
    int nBytesPacket = nBytesMsg + nTipBytes;
    out_packet.assign(nBytesPacket, '\0');

    google::protobuf::io::ArrayOutputStream aos((void*)out_packet.c_str(), nBytesPacket);
    google::protobuf::io::CodedOutputStream cos(&aos);
    cos.WriteVarint32(nBytesMsg);   
    bool res = pPayload->SerializeToCodedStream(&cos);
    printf("payload has message: %d\n", pPayload->has_msg());
    //
    // Decoding
    //
    Pouch out_pouch;
    google::protobuf::io::ArrayInputStream ais(out_packet.c_str(), nBytesPacket);
    google::protobuf::io::CodedInputStream cis(&ais);
    google::protobuf::uint32 nPayloadBytes;
    cis.ReadVarint32(&nPayloadBytes);   
    google::protobuf::io::CodedInputStream::Limit msgLimit = cis.PushLimit(nPayloadBytes);
    res = out_pouch.ParseFromCodedStream(&cis);
    cis.PopLimit(msgLimit);

    printf("decoded payload has message: %d\n", out_pouch.has_msg());
    if (out_pouch.has_msg()){
        Sample s;
        out_pouch.msg().UnpackTo(&s);
        printf("value: %d\n", s.number());
    }

    pPayload->release_msg();
    return res;
}

int main(){
    Sample *mymsg = new Sample();
    mymsg->set_number(5123);
    std::string bigstring;
    EncodeDecode(mymsg, bigstring);
}
syntax = "proto3";
import "google/protobuf/any.proto";

message Pouch {
    google.protobuf.Any msg = 1;
}

message Sample {
    int32 number = 1;
}