free website counter

Protobuf在C++、Python环境下的应用

  Protobuf官方支持将proto文件编译成C++, Python, PHP的类,而利用一些开源类库,可以对ruby、php等常见的脚本语言进行支持。项目中需要使用Protobuf的地方,主要在于C++与C++之间的接口,以及Python与C++之间的接口。下面分别针对C++以及Python下的Protobuf,实现序列化及反序列化。

1. user.proto

package user;                                                                                      
message Person {
    required string name = 1;
    required int32 id = 2;
    optional string email = 3;
}

  可以认为user是namaspace,而Person是这个命名空间之内的类。使用protoc -I ./ - - cpp_out ./cpp user.proto即可编译出C++所需要的user.pb.cc以及user.pb.h,其中-I指定proto所在的目录,cpp_out指定生成的类所在路径。


2. C++下的序列化与反序列化

2.1 测试代码

#include "user.pb.h"                                                                                                                                                                    
#include <fstream>
#include <iostream>
//#include <unistd.h>

using namespace std;

void ListMsg(const user::Person & user)
{
    cout << user.name() << endl;
    cout << user.id() << endl;
    cout << user.email() << endl;
}

int main(void)
{   
    user::Person user1;
    user1.set_name("Mushsen");
    user1.set_id(8008);
    user1.set_email("mushsen@163.com");
    fstream output("./log", ios::out | ios::trunc | ios::binary);

    if (!user1.SerializeToOstream(&output)) {
         cerr << "Failed to write msg." << endl;
         return -1;
    }
    output.close();
    //slppe(1);

    user::Person user2;
    fstream input("./log", ios::in | ios::binary);
    if (!user2.ParseFromIstream(&input)) {
         cerr << "Failed to parse address book." << endl;
         return -1;
    }
    input.close();
    ListMsg(user2);
    return 0; 
}

  注意input, output输入输出文件流一定要关闭,要不在读取的时候,由于并未刷新,将读不到数据,required字段没有值,报错。

2.2 相应的Makefile

all: user                                                                                                                                                                               

clean:
      rm -f user  *.o  log  

user: user.pb.cc user.cpp
    g++  user.pb.cc user.cpp -o user  `pkg-config --cflags --libs protobuf`


3. Python下的序列化与反序列化

  使用protoc -I ./ - -python_out ./py user.ptoto即可编译出python所需要的user_pb2.py文件,在需要使用的地方import即可。

#!/usr/bin/env python                                                                                                                                                                   
#coding=utf-8

import user_pb2

person1 = user_pb2.Person()
person1.id = 7007
person1.name = "Mushsen"
person1.email = "mushsen@gmail.com"
person_serial = person1.SerializeToString()

print person_serial
print '------------'

person2 = user_pb2.Person()
person2.ParseFromString(person_serial)
print person2.id
print person2.name
print person2.email
Published 05 June 2015
分享按钮