您的位置:首页 > 编程语言 > Go语言

Google Protobuf - 实现跨平台跨语言的序列化/反序列化

2012-03-28 18:39 846 查看
转载请注明来自“柳大的CSDN博客”:Blog.CSDN.net/Poechant

Google Protocol Buffer 是一个平台无关、语言无关的结构化数据的序列化与反序列化工具。


1 Establish dev environment

[code]wget http://protobuf.googlecode.com/files/protobuf-2.4.1.tar.gz tar zxvf protobuf-2.4.1.tar.gz
cd protobuf-2.4.1
mkdir /Users/michael/Development/opt/protobuf-2.4.1
./configure --prefix=/Users/michael/Development/opt/protobuf-2.4.1
make
make check
make install


2 Protocol file

创建一个名为 lm.helloworld.proto 的文件。
[code]package lm;
message helloworld
{
    required int32  id = 1;     // ID
    required string str = 2;    // str
    optional int32  opt = 3;    // optional field
}

一般 Google Protobuf 的 protocol 文件名形如:
[code]packageName.MessageName.proto


3 Generate protocol classes

此时的目录结构:
[code]protobuf-2.4.1
|---bin
|---include
|---lib
|---test
    |---lm.helloworld.proto

编译生成 Google Protobuf 类文件:
[code]alias protoc='/Users/michael/Development/opt/protobuf-2.4.1/bin/protoc'
SRC_DIR=.
DST_DIR=.
protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/lm.helloworld.proto

此时的目录结构为:
[code]protobuf-2.4.1
|---bin
|---include
|---lib
|---test
    |---lm.helloworld.proto
|---lm.helloworld.pb.cc
|---lm.helloworld.pb.h


4 Application files

此处以 File Stream 为例。


4.1 Structured data -> Stream

[code]#include "lm.helloworld.pb.h"
#include <iostream>
#include <fstream>

using namespace std;

int main(void)
{
    lm::helloworld msg1;
    msg1.set_id(101);
    msg1.set_str("hello");

    fstream output("./log", ios::out | ios::trunc | ios::binary);

    if (!msg1.SerializeToOstream(&output))
    {
        cerr << "Failed to write msg." << endl;
        return -1;
    }
    return 0;
}

跟已有的结构化数据结构(依据 Google Protobuf 的格式)创建数据,将结构化数据序列化到流中。


4.2 Stream -> Structured data

[code]#include "lm.helloworld.pb.h"                                                                                                                                                                             
#include <iostream>
#include <fstream>

using namespace std;

void ListMsg(const lm::helloworld & msg)
{
    cout << msg.id() << endl; 
    cout << msg.str() << endl; 
} 

int main(int argc, char* argv[])
{ 
    lm::helloworld msg1;
    {   
        fstream input("./log", ios::in | ios::binary);
        if (!msg1.ParseFromIstream(&input))
        {   
            cerr << "Failed to parse address book." << endl;
            return -1; 
        }   
    }   
    ListMsg(msg1);
}

将流中的序列化数据,读取到依据 Google Protobuf 的格式创建的对象中。


5 Compile executable files


5.1 Directories and file tree

[code]protobuf-2.4.1
|---bin
|---include
|---lib
|---test
    |---lm.helloworld.proto
|---lm.helloworld.pb.cc
|---lm.helloworld.ph.h
|---write.cpp
|---read.cpp


5.2 Compile

[code]g++ lm.helloworld.pb.cc write.cpp -o write.out -I ../include -L../lib -lprotobuf

Notice:

编译应用程序源文件时,要记得同时编译 lm.helloworld.pb.cc 源文件;
记得 Include Google Protobuf headers(-I ../include)
记得 Link 路径以及相应的 google protobuf libraries(-L../lib -lprotobuf)


6 Run

运行 write:
[code]./write

会观察到生成如下文件(参见源程序):
[code]log

运行 read:
[code]./read

输出结果:
[code]$ ./read.out 
101
hello


7 Review

环境:搭建 Google Protobuf 的开发环境;
协议:根据 Google Protobuf 格式要求,创建 Protocol 文件;
生成:利用 protoc 编译生成所定义的 Protocol 的类源文件与头文件;
应用:编写利用所生成的 Protocol 的类源文件与头文件;
编译:编译所编写的应用的源文件与头文件,注意头文件路径、库文件路径及库;
运行。


Reference

http://stackoverflow.com/questions/8875867/linking-errors-when-using-proto-tutorial http://www.ibm.com/developerworks/cn/linux/l-cn-gpb/ http://code.google.com/intl/zh-CN/apis/protocolbuffers/docs/overview.html

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: