转帖第二弹:《Protocol Buffers相关基础知识》

来源:互联网 发布:火车头采集器 帝国cms 编辑:程序博客网 时间:2024/06/06 07:19

http://code.google.com/p/protobuf/downloads/list

官方文档

晚上刚写了一篇《Protocol Buffers 简介》,然后就开始动手实战试用一下 Protocol Buffers 这个 Google 出品的东东。

首先从 Protocol Buffers 的主页上把源码下回来,注意是源码,那个 Win32 包不必下,它里面只有一个编译好的 protoc.exe,没有开发所必须的库,光有那个 Protocol Buffers 编译器是没用。

将源码解压出来以后,直接到 vsprojects 目录下用 Visual Studio 2005(其它版本我没有试)打开解决方案文件 protobuf.sln 开始编译。编译成功结束后会在解决方案目录下生成一个 google 目录,里面是单元测试的程序;另外就是 Debug 目录和 Release 目录了,生成的对应版本的 .lib 和 .dll 还有 protoc.exe 编译器全在里面。

那么,头文件呢?在解决方案目录下有一个 extract_includes.bat 文件看到了吗,执行后会生成一个 include 目录,里面就是使用 Protocol Buffers 开发必须的所有头文件了。

HiaHia~ 有了这几样东西,Protocol Buffers 这个强大武器才算是真正到手了。在动手写我们自己的程序之前,为了方便,你也可以把库文件和头文件单独存放在别处,然后在 VC 里设置 VC++ 目录就行了,还有别忘了把 .dll 所在的目录加到系统的 Path 环境变量中。好了,现在我们可以开始动手写自己的程序啦!其实这个程序就是 Protocol Buffers 文档中的电话本例子,只不过我自己试了一遍而已。

第一步,写一个 .proto 文件描述数据结构:

// addressbook.proto
//package tutorial;

option java_package = “com.example.tutorial”;
option java_outer_classname = “AddressBookProtos”;

message Person {
required string name = 1;
required int32 id = 2; // Unique ID number for this person.
optional string email = 3;

enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}

message PhoneNumber {
required string number = 1;
optional PhoneType type = 2 [default = HOME];
}

repeated PhoneNumber phone = 4;
}

// Our address book file is just one of these.
message AddressBook {
repeated Person person = 1;
}

第二步,使用命令 protoc.exe -I=. –cpp_out=. addressbook.proto 编译 addressbook.proto,或者方便起见,在 VC 里给 addressbook.proto 设置自定义生成步骤,命令还是这一行,输出文件设置为 addressbook.pb.h;addressbook.pb.cc。

第三步,新建 testProtocolBuffers.cpp,写入下面的代码:

// testProtocolBuffers.cpp : Defines the entry point for the console application.
//#include <iostream>
#include <fstream>
#include <string>
#include “addressbook.pb.h”
#pragma comment(lib, “libprotobuf.lib”)

void PromptForAddress(tutorial::Person* person);
void ListPeople(const tutorial::AddressBook& addressbook);

int AddPerson();
int ViewPerson();

int _tmain(int argc, _TCHAR* argv[])
{
AddPerson();
ViewPerson();
return 0;
}

void PromptForAddress(tutorial::Person* person)
{
std::cout <<”Enter person ID number: “;
int id;
std::cin>> id;
person->set_id(id);
std::cin.ignore(256, ‘/n’);

std::cout <<”Enter name: “;
std::getline(std::cin, *person->mutable_name());

std::cout <<”Enter email address (blank for none): “;
std::string email;
std::getline(std::cin, email);
if (!email.empty())
person->set_email(email);

while (true)
{
std::cout <<”Enter a phone number (or leave blank to finish): “;
std::string number;
std::getline(std::cin, number);
if (number.empty())
break;

tutorial::Person::PhoneNumber* phonenum = person->add_phone();
phonenum->set_number(number);

std::cout <<”Is it a mobile, home or work phone? “;
std::string type;
std::getline(std::cin, type);
if (“mobile” == type)
phonenum->set_type(tutorial::Person::MOBILE);
else if (“home” == type)
phonenum->set_type(tutorial::Person::HOME);
else if (“work” == type)
phonenum->set_type(tutorial::Person::WORK);
else
std::cout <<”Unknown phone type. Using default.” <<std::endl;
}
}

void ListPeople(const tutorial::AddressBook& addressbook)
{
for (int i = 0; i <addressbook.person_size(); i++)
{
const tutorial::Person& person = addressbook.person(i);
std::cout <<”Person ID: ” <<person.id() <<std::endl;
std::cout <<”Name: ” <<person.name() <<std::endl;
if (person.has_email())
std::cout <<”Email: ” <<person.email() <<std::endl;

for (int j = 0; j <person.phone_size(); j++)
{
const tutorial::Person::PhoneNumber& phonenum = person.phone(j);
switch (phonenum.type())
{
case tutorial::Person::MOBILE:
std::cout <<”Mobile phone #: “;
break;
case tutorial::Person::HOME:
std::cout <<”Home phone #: “;
break;
case tutorial::Person::WORK:
std::cout <<”Work phone #: “;
break;
}
std::cout <<phonenum.number() <<std::endl;
}
}
}

int AddPerson()
{
tutorial::AddressBook addressbook;
const std::string& filename = “addressbook”;
std::fstream input(filename.c_str(), ios::in | ios::binary);
if (!input)
std::cout <<filename <<”: File not found. Creating a new file.” <<std::endl;
else if (!addressbook.ParseFromIstream(&input))
{
std::cerr <<”Failed to parse address book.” <<std::endl;
return -1;
}
PromptForAddress(addressbook.add_person());
std::fstream output(filename.c_str(), ios::out | ios::trunc | ios::binary);
if (!addressbook.SerializeToOstream(&output))
{
std::cerr <<”Failed to write address book.” <<std::endl;
return -1;
}
return 0;
}

int ViewPerson()
{
tutorial::AddressBook addressbook;
const std::string& filename = “addressbook”;
std::fstream input(filename.c_str(), ios::in | ios::binary);
if (!addressbook.ParseFromIstream(&input))
{
std::cerr <<”Failed to parse address book.” <<std::endl;
return -1;
}
ListPeople(addressbook);
return 0;
}

编译——链接,这样我们的第一个程序,基于 Protocol Buffers 的电话本就写好了。时间关系,这篇日志写得很匆忙。程序在 VC2005 下测试通过,但这只是一个小例子,至于 Protocol Buffers 的性能和效率还没有来得及进一步测试。^_^

原创粉丝点击