【protocolbuff】linux下安装protobuf[实践] --未成功|Protocol Buffer 使用教程

目录

linux下安装protobuf

1、protobuf用法

2、linux下安装google protobuf

何为 ProtoBuf

使用 ProtoBuf

关于 ProtoBuf 的一些思考

Windows Protocol Buffer 使用教程

protocolbuffer 简介

安装

1、protocol 编译器

2、protobuf  运行库

3、protobuf 和protoc的区别

protobuf:

protoc:

使用

1.      下载源码。

2.      编译源码生产解析库。

3.      生产include文件。

4.    编写*.proto文件(UserInfo.proto)

5、用protoc 处理[*.proto文件]生成 [*.proto]定义的数据对应的解析函数接口文件

6、将生成的文件加入到工程中

何为 ProtoBuf

使用 ProtoBuf

关于 ProtoBuf 的一些思考


前言

数据通信-序列化协议protocoljson-https://download.csdn.net/download/bandaoyu/86542158

linux下安装protobuf

1、protobuf用法

1、编写*.proto文件(UserInfo.proto)

package Test;
message userninfo
{
required string name = 1;
required string mail = 2;
required string time = 3;
optional string status = 4;
}

2、用protoc 处理[*.proto文件]生成指定语言(--cpp_out)的解析函数接口文件

protoc --cpp_out=.\ .\user.proto

在.\目录下生成接口文件:user.pb.cc、user.pb.h

3、将生成的文件user.pb.cc、user.pb.h加入到工程中

将生成的文件user.pb.cc、user.pb.h加入到工程中,并将libprotobuf.lib、libprotoc.lib、libprotobuf-lite.lib 添加到工程依赖目录中,专业就可以调用生成的文件内的方法解析数据了。

更多请看:【Protocol Buffer】Windows Protocol Buffer 使用教程[实践中...]_bandaoyu的博客-CSDN博客

2、linux下安装google protobuf

参考:linux下安装google protobuf(详细)_jackytse_的博客-CSDN博客_linux protobuf安装

说明:
protobuf已经全面迁移到github,地址:GitHub - protocolbuffers/protobuf: Protocol Buffers - Google's data interchange format
直接下载2.6.1版本:https://github.com/google/protobuf/archive/v2.6.1.zip

默认安装:

$wget https://github.com/google/protobuf/archive/v2.6.1.zip
$unzip protobuf-2.6.1.zip #这里我下载得到的文件是v2.6.1,所以改为unzip v2.6.1
$cd protobuf-2.6.1

 下载自github的代码需要首先执行 $ ./autogen.sh 生成configure文件但注意autogen.sh 需要gtest包,默认是从 googletest.googlecode.com下载,国内需要FQ才能访问,很多人问autogen.sh运行失败,这里我补充一下
修改一下autogen.sh
将这段:

echo "Google Test not present.  Fetching gtest-1.5.0 from the web..."

curl http://googletest.googlecode.com/files/gtest-1.5.0.tar.bz2 | tar jx

mv gtest-1.5.0 gtest

修改为:

wget https://github.com/google/googletest/archive/release-1.5.0.tar.gz
tar xzvf release-1.5.0.tar.gz  #发现下载的文件没有后缀名,所以我改成tar xzvf release-1.5.0
mv googletest-release-1.5.0 gtest

(我这里还是会报错,因为的下下来的文件没有后缀名:release-1.5.0,所以我手工执行了

tar xzvf release-1.5.0.tar.gz
mv googletest-release-1.5.0 gtest

然后再重新执行autogen.sh 才通过)

$ ./configure 
$ make 
$ make check 
$ make install 
我使用的是centos系统 
/usr/local/bin 
/usr/local/lib, 
/usr/local/include 是也系统默认路径之一,所以到这一步就可以使用protobuf了 
$ protoc -I=./ --cpp_out=./ test.proto 
到你的test.proto文件所在目录使用命令
protoc -I=./ --cpp_out=./ 生成C++版本的协议文件 
一切OK的话,你回在当前目录看到.h和.cc文件

之前在网络通信和通用数据交换等应用场景中经常使用的技术是 JSON 或 XML,而在最近的开发中接触到了 Google 的 ProtoBuf。

在查阅相关资料学习 ProtoBuf 以及研读其源码之后,发现其在效率、兼容性等方面非常出色。在以后的项目技术选型中,尤其是网络通信、通用数据交换等场景应该会优先选择 ProtoBuf。

自己在学习 ProtoBuf 的过程中翻译了官方的主要文档,一来当然是在学习 ProtoBuf,二来是培养阅读英文文档的能力,三来是因为 Google 的文档?不存在的!

看完这些文档对 ProtoBuf 应该就有相当程度的了解了。

翻译文档见 [索引]文章索引,导航为翻译 - 技术 - ProtoBuf 官方文档。

但是官方文档更多的是作为查阅和权威参考,并不意味着看完官方文档就能立马理解其原理。

本文以及接下来的几篇文章会对 ProtoBuf 的编码、序列化、反序列化、反射等原理做一些详细介绍,同时也会尽量将这些原理表达的更为通俗易懂。

何为 ProtoBuf

我们先来看看官方文档给出的定义和描述:

protocol buffers 是一种语言无关、平台无关、可扩展的序列化结构数据的方法,它可用于(数据)通信协议、数据存储等。

Protocol Buffers 是一种灵活,高效,自动化机制的结构数据序列化方法-可类比 XML,但是比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单。

你可以定义数据的结构,然后使用特殊生成的源代码轻松的在各种数据流中使用各种语言进行编写和读取结构数据。你甚至可以更新数据结构,而不破坏由旧数据结构编译的已部署程序。

简单来讲, ProtoBuf 是结构数据序列化[1] 方法,可简单类比于 XML[2],其具有以下特点:

  • 语言无关、平台无关。即 ProtoBuf 支持 Java、C++、Python 等多种语言,支持多个平台
  • 高效。即比 XML 更小(3 ~ 10倍)、更快(20 ~ 100倍)、更为简单
  • 扩展性、兼容性好。你可以更新数据结构,而不影响和破坏原有的旧程序

序列化[1]:将结构数据对象转换成能够被存储和传输(例如网络传输)的格式,同时应当要保证这个序列化结果在之后(可能在另一个计算环境中)能够被重建回原来的结构数据或对象。
更为详尽的介绍可参阅 维基百科类比于 XML[2]:这里主要指在数据通信和数据存储应用场景中序列化方面的类比,但个人认为 XML 作为一种扩展标记语言和 ProtoBuf 还是有着本质区别的。

使用 ProtoBuf

对 ProtoBuf 的基本概念有了一定了解之后,我们来看看具体该如何使用 ProtoBuf。第一步,创建 .proto 文件,定义数据结构,如下例1所示:

// 例1: 在 xxx.proto 文件中定义 Example1 message
message Example1 {
    optional string stringVal = 1;
    optional bytes bytesVal = 2;
    message EmbeddedMessage {
        int32 int32Val = 1;
        string stringVal = 2;
    }
    optional EmbeddedMessage embeddedExample1 = 3;
    repeated int32 repeatedInt32Val = 4;
    repeated string repeatedStringVal = 5;
}

我们在上例中定义了一个名为 Example1 的 消息,语法很简单,message 关键字后跟上消息名称:

message xxx {

}

之后我们在其中定义了 message 具有的字段,形式为:

message xxx {
  // 字段规则:required -> 字段只能也必须出现 1 次
  // 字段规则:optional -> 字段可出现 0 次或1次
  // 字段规则:repeated -> 字段可出现任意多次(包括 0)
  // 类型:int32、int64、sint32、sint64、string、32-bit ....
  // 字段编号:0 ~ 536870911(除去 19000 到 19999 之间的数字)
  字段规则 类型 名称 = 字段编号;
}

在上例中,我们定义了:

  • 类型 string,名为 stringVal 的 optional 可选字段,字段编号为 1,此字段可出现 0 或 1 次
  • 类型 bytes,名为 bytesVal 的 optional 可选字段,字段编号为 2,此字段可出现 0 或 1 次
  • 类型 EmbeddedMessage(自定义的内嵌 message 类型),名为 embeddedExample1 的 optional 可选字段,字段编号为 3,此字段可出现 0 或 1 次
  • 类型 int32,名为 repeatedInt32Val 的 repeated 可重复字段,字段编号为 4,此字段可出现 任意多次(包括 0)
  • 类型 string,名为 repeatedStringVal 的 repeated 可重复字段,字段编号为 5,此字段可出现 任意多次(包括 0)

关于 proto2 定义 message 消息的更多语法细节,例如具有支持哪些类型,字段编号分配、import
导入定义,reserved 保留字段等知识请参阅 [翻译] ProtoBuf 官方文档(二)- 语法指引(proto2)

关于定义时的一些规范请参阅 [翻译] ProtoBuf 官方文档(四)- 规范指引

第二步,protoc 编译 .proto 文件生成读写接口

我们在 .proto 文件中定义了数据结构,这些数据结构是面向开发者和业务程序的,并不面向存储和传输。

当需要把这些数据进行存储或传输时,就需要将这些结构数据进行序列化、反序列化以及读写。那么如何实现呢?不用担心, ProtoBuf 将会为我们提供相应的接口代码。如何提供?答案就是通过 protoc 这个编译器。

可通过如下命令生成相应的接口代码:

// $SRC_DIR: .proto 所在的源目录
// --cpp_out: 生成 c++ 代码
// $DST_DIR: 生成代码的目标目录
// xxx.proto: 要针对哪个 proto 文件生成接口代码

protoc -I=$SRC_DIR --cpp_out=$DST_DIR $SRC_DIR/xxx.proto

最终生成的代码将提供类似如下的接口:

例子-序列化和解析接口.png

例子-protoc 生成接口.png

第三步,调用接口实现序列化、反序列化以及读写
针对第一步中例1定义的 message,我们可以调用第二步中生成的接口,实现测试代码如下:

//
// Created by yue on 18-7-21.
//
#include <iostream>
#include <fstream>
#include <string>
#include "single_length_delimited_all.pb.h"

int main() {
    Example1 example1;
    example1.set_stringval("hello,world");
    example1.set_bytesval("are you ok?");

    Example1_EmbeddedMessage *embeddedExample2 = new Example1_EmbeddedMessage();

    embeddedExample2->set_int32val(1);
    embeddedExample2->set_stringval("embeddedInfo");
    example1.set_allocated_embeddedexample1(embeddedExample2);

    example1.add_repeatedint32val(2);
    example1.add_repeatedint32val(3);
    example1.add_repeatedstringval("repeated1");
    example1.add_repeatedstringval("repeated2");

    std::string filename = "single_length_delimited_all_example1_val_result";
    std::fstream output(filename, std::ios::out | std::ios::trunc | std::ios::binary);
    if (!example1.SerializeToOstream(&output)) {
        std::cerr << "Failed to write example1." << std::endl;
        exit(-1);
    }

    return 0;
}

关于 pro

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值