在C++中使用Google的“Protocol Buffers”
来源:互联网 发布:最小生成树kruskal算法 编辑:程序博客网 时间:2024/06/13 09:39
如果您已经初步了解了Protocol Buffers并打算试着使用它,本文符合您的胃口。如果您刚听说Protocol Buffers,请先到本文末尾的附录区看一看。
1.下载并安装Protocol Buffers
可以从官方下载源码包,linux下和Solaris下的安装直接见源码包中的“README.txt”。这里详细说下Windows下的安装,源码包里有一个“vsprojects”目录,其中就是vs的工程文件和解决方案。用vs(版本得高点)打开“protobuf.sln”解决方案,编译。其中包括四个工程 libprotobuf(接口dll库)、libprotoc(转换器的实现库)、protoc(windows下转换器的实现)、tests(使用gTest库进行的测试)。编译好之后在Debug目录下可以找到“libprotobuf.dll、libprotobuf.lib”,这个是我们的程序要使用的动态链接库和导入库。“libprotoc.dll、libprotoc.lib”,这个是完成.proto文件到cpp、java、python格式数据转换的库。“protoc.exe”,这个是windows下转换程序(它使用了刚才的libprotoc库),这个程序的静态链接版本也在此项目老家提供下载。
2.设置编译环境
linux下,只要将Protocol Buffers源码包安装到系统即可开始使用。而windows下需要设置一下编译环境,将“src”目录加入到编译器的头文件搜索路径,将“vsprojects/Debug”目录加入到编译器的lib搜索路径中。为了更方便的在windows命令行下使用protoc.exe转换程序,可以将“vsprojects/Debug”目录添加到系统PATH变量中。
3.编写.proto数据描述文件
这里仿照源码中例子,写出“addressbook.proto”文件。内容如下:
--code begin--
package tutorial;message Person { required string name = 1; required int32 id = 2; 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;}message AddressBook { repeated Person person = 1;}
--code end--
4.使用protoc(windows下是protoc.exe)生成c++头文件及类文件。
protoc.exe --cpp_out=./ addressbook.proto
如果没有错误,程序将没有任何输出。并且当前目录下多出两个文件“addressbook.pb.h”和“addressbook.pb.cc”。
5.编写C++程序使用它们
新建vs工程,除了设置以上的头文件搜索路径和库文件搜索路径外,还要链接到库“libprotobuf.lib”。将4步生成的一个.h文件和一个.cpp文件添加并拷贝到工程里,由于vs的特性(需要预编译头),所以在addressbook.pb.cc开头添加“#include "stdafx.h"”,主代码如下,然后编译。这个演示程序需要一个参数用于指定数据文件文件名,第一次运行,会生成这个数据文件。它会先让用户输入一条通讯录信息并添加进数据文件,然后再显示出指定的数据文件中所有的数据。注意,为了使DEMO程序可以运行,别忘了拷贝“vsprojects/Debug”目录下的动态链接库“libprotobuf.dll”到当前目录。
--code begin--
// testprotocolbuffer.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"// See README.txt for information and build instructions.#include <iostream>#include <fstream>#include <string>#include "addressbook.pb.h"using namespace std;// This function fills in a Person message based on user input.void PromptForAddress(tutorial::Person* person) { cout << "Enter person ID number: "; int id; cin >> id; person->set_id(id); cin.ignore(256, '/n'); cout << "Enter name: "; getline(cin, *person->mutable_name()); cout << "Enter email address (blank for none): "; string email; getline(cin, email); if (!email.empty()) { person->set_email(email); } while (true) { cout << "Enter a phone number (or leave blank to finish): "; string number; getline(cin, number); if (number.empty()) { break; } tutorial::Person::PhoneNumber* phone_number = person->add_phone(); phone_number->set_number(number); cout << "Is this a mobile, home, or work phone? "; string type; getline(cin, type); if (type == "mobile") { phone_number->set_type(tutorial::Person::MOBILE); } else if (type == "home") { phone_number->set_type(tutorial::Person::HOME); } else if (type == "work") { phone_number->set_type(tutorial::Person::WORK); } else { cout << "Unknown phone type. Using default." << endl; } }}// Iterates though all people in the AddressBook and prints info about them.void ListPeople(const tutorial::AddressBook& address_book) { for (int i = 0; i < address_book.person_size(); i++) { const tutorial::Person& person = address_book.person(i); cout << "Person ID: " << person.id() << endl; cout << " Name: " << person.name() << endl; if (person.has_email()) { cout << " E-mail address: " << person.email() << endl; } for (int j = 0; j < person.phone_size(); j++) { const tutorial::Person::PhoneNumber& phone_number = person.phone(j); switch (phone_number.type()) { case tutorial::Person::MOBILE: cout << " Mobile phone #: "; break; case tutorial::Person::HOME: cout << " Home phone #: "; break; case tutorial::Person::WORK: cout << " Work phone #: "; break; } cout << phone_number.number() << endl; } }}// Main function: Reads the entire address book from a file,// adds one person based on user input, then writes it back out to the same// file.int main(int argc, char* argv[]) { // Verify that the version of the library that we linked against is // compatible with the version of the headers we compiled against. GOOGLE_PROTOBUF_VERIFY_VERSION; if (argc != 2) { cerr << "使用方法: " << argv[0] << " 想要生成的存储数据的文件" << endl; return -1; } tutorial::AddressBook address_book; { // Read the existing address book. fstream input(argv[1], ios::in | ios::binary); if (!input) { cout << argv[1] << ": 指定的文件没找到,创建一个新文件." << endl; } else if (!address_book.ParseFromIstream(&input)) { cerr << "解析addressbook数据文件失败。" << endl; return -1; } } // Add an address. PromptForAddress(address_book.add_person()); { // Write the new address book back to disk. fstream output(argv[1], ios::out | ios::trunc | ios::binary); if (!address_book.SerializeToOstream(&output)) { cerr << "写入文件失败。" << endl; return -1; } } //再从文件中读取刚才那个数据 tutorial::AddressBook address_book2; { // Read the existing address book. fstream input(argv[1], ios::in | ios::binary); if (!address_book2.ParseFromIstream(&input)) { cerr << "解析文件失败。" << endl; return -1; } } ListPeople(address_book2); return 0;}
--code end--
运行方式和结果如下图:
备注:写这东西好累啊。。。
- 【Protocol Buffers】在Flash中使用Google Protocol Buffers
- 在Flash中使用Google Protocol Buffers
- 在C#中使用Google Protocol Buffers
- 在C++中使用Google的“Protocol Buffers”
- Protocol Buffers在Objective-C上的使用
- Protocol Buffers在iOS中使用的简单介绍
- 在 iOS 中使用 Protocol Buffers
- 在C++中使用Protocol Buffers
- 在Java中使用Protocol Buffers
- 在Android中使用Protocol Buffers
- protocol buffers c语言的使用
- Protocol Buffers在mac下的使用
- Google Protocol Buffers在linux环境下的安装
- Google Protocol Buffers在linux环境下的安装
- google protocol buffers介绍(c++)
- Google Protocol Buffers安装、使用二三事
- Google Protocol Buffers安装和使用
- Google Protocol Buffers安装、使用二三事
- squid 缓存 nginx,gzip设置
- 人脉经营全攻略:认识、经营与开发
- 不惑之礼
- 确保实现“十一五”节能减排目标
- Error: Read from storage 0 bytes, but requested 12 bytes 的解决方法
- 在C++中使用Google的“Protocol Buffers”
- POJ_2559
- 获取IWebBrowser2指针的方法(二)
- js 动态加载function(onclick= function ())
- Visual SourceSafe 学习笔记(二)
- C#中父窗口和子窗口之间实现控件互操作
- Linux挑战基因网络——电脑操作系统与生物基因网络之对比
- InstallShield内部库函数全集(中文版)
- SSH连接的时候Host key verification failed.