protobuf 使用说明和各种坑

本文介绍了一个使用Protobuf进行结构体定义的方法,并通过C++实现序列化与反序列化的具体过程。作者详细记录了从创建.proto文件、编译到在main.cpp中进行数据写入和读取的操作步骤及遇到的问题。特别关注了如何正确地处理多个消息的序列化和反序列化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

需要弄一个写结构体的类,想到protubuf,经过各种坑,总结如下,希望帮助需要到人

我的proto文件:

//option optimize_for = LITE_RUNTIME;
message Node{
    required int64 nodeId = 1;
    required string passwd = 2;
    required double x = 3;
    //required double y = 4;
    //required int64 parrendId = 5;
    //required double distendParrent = 6;
}

使用protoc 文件 --cpp_out .  输出.cc 和 .h 文件

编译Makefiile( 简单写的):

all:
	protoc node.proto --cpp_out .
	g++ main.cpp node.pb.cc `pkg-config --libs --cflags protobuf` -g

测试文件,主要是main.cpp:

/*************************************************************************
	> File Name: main.cpp
	> Author: MaShiChuan
	> Mail: 981880785@qq.com
	> Created Time: 2016年12月17日 星期六 11时22分44秒
 ************************************************************************/

#include<iostream>
#include "node.pb.h"
#include <fstream>
using namespace std;
int main(){
    GOOGLE_PROTOBUF_VERIFY_VERSION; 
    fstream fout("d.dat",ios::out|ios::binary);
    Node a;
    a.set_nodeid(3);
    a.set_x(3.3);
    a.set_passwd("33");
    a.SerializeToOstream(&fout); 
    a.set_nodeid(4);
    a.SerializeToOstream(&fout); 
    a.SerializeToOstream(&fout); 
    fout.close();
    fstream fin("d.dat",ios::in|ios::binary);
    string line;
    do{
        Node b;
        getline(fin,line,'@');
        if(line == ""){
            break;
        }
        //cout<<line<<endl;
        //b.ParseFromIstream(&fin);
        b.ParseFromString(line);
        cout<<b.nodeid()<<endl;
        cout<<b.passwd()<<endl;
    }while(!fin.eof());
    google::protobuf::ShutdownProtobufLibrary();
    return 0;
}

使用方法:

proto文件中规定好有那些东西需要存储,main.cpp中设置值, 相关函数可以从.cc文件中找找。不多说。

有关如何序列化和反序列化,参考下面的文档,

我遇到的问题是,向文件中写了三个message,想依次读出了来,结果反序列化与序列化不对应,总是读最后一个message.

ParseFromStream不能用,用 cat data文件打开是有分行的,想用ParseFromString,分行解析,结果还是不行,

网上查类许多资料,没说怎么处理,索性把data文件打开看看,od -a  查看如下:

0000000  bs etx dc2 stx   3   3  em   f   f   f   f   f   f  nl   @  bs
0000020 eot dc2 stx   3   3  em   f   f   f   f   f   f  nl   @  bs eot
0000040 dc2 stx   3   3  em   f   f   f   f   f   f  nl   @
0000055

明显有个分割符@,getline函数正好有个输入分隔符的参数,难道要用@分行,然后试了试,发现果然可以。

希望能帮助需要的人。

参考文档:

入门手册:

http://www.cnblogs.com/stephen-liu74/archive/2013/01/04/2842533.html

类型说明:

http://blog.youkuaiyun.com/superbfly/article/details/17920383

参考手册:

http://pages.cs.wisc.edu/~starr/bots/Undermind-src/html/annotated.html

常用序列化函数:

http://blog.youkuaiyun.com/sealyao/article/details/6940245

转载于:https://my.oschina.net/u/2265334/blog/807565

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值