linux环境下protobuf的安装与使用

一、protobuf的下载安装

1、protobuf的下载:这里。此处下载的是protobuf-cpp-3.9.1.tar.gz。

2、安装准备:安装protobuf前确保以下软件都已经被安装。方法也很简单yum -y install XXXX即可。

autoconf
automake 
libtool   
make  
g++  
unzip

注:值得注意的是我们要将g++设为默认使用C++11,可以在终端执行:

alias g++='g++ -std=c++11'

但是切记:这个只是临时生效的,永久有效的方法是将上述语句写入/root/.bashrc 文件中。

vim /root/.bashrc

添加:alias g++='g++ -std=c++11'

3、安装protobuf

执行如下命令,安装时间有点长,耐心等待(可以写成自动化脚本,就无需一步一步执行):

./configure 
make  #时间有点长
make check  #时间有点长
sudo make install 
sudo ldconfig  # refresh shared library cache.

这时一般来说
libprotobuf库在/usr/local/lib路径下;protoc一般在/usr/local/bin路径下 。如下:

4、配置环境变量

主要是完善PATH和PKG_CONFIG_PATH等环境变量

$ sudo vim /etc/profile

添加

export PATH=$PATH:/usr/local/bin/
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/  #这个参数是必须的

#我添加了这些,感觉有些没有也可以。
export PATH=$PATH:/usr/local/bin
export PATH=$PATH:/usr/local/include
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

保存生效

source /etc/profile

注:(1)保存生效的语句需要在每个终端都执行一遍才可以生效;

(2)通过echo $PATH   /  echo $PKG_CONFIG_PATH的方法验证配置在本终端有没有生效。

(3)上述配置中PKG_CONFIG_PATH是必须的(当然其他可能也是必须的),如果没有在编译的时候会报如下错误:

这里的protobuf.pc存了protobuf相关的头文件和库相关的信息,这些信息都是编译的时候要用到的。这里是因为我们使用了pkg-config来方便引用了的,关于pkg-config参见 这里。

5、配置动态路径

sudo vim /etc/ld.so.conf

追加

/usr/local/lib

然后以root权限更新动态库路径

ldconfig

6、验证有没有安装成功

执行:

protoc --version

能够显示相应版本信息就说明安装成功。

 

二、使用举例

1、person.proto文件:

syntax = "proto3";#指定使用proto3
package tencent; #命名空间

message Person
{
    string name = 1;
    uint32 age  = 2;
    uint64 phnum = 3;
}

注意:proto3和proto2的区别还是蛮大的,此处没有了proto2中常见的optional、required之类的修饰。

2、编译.proto文件。执行如下指令对.proto文件按照c++的形式进行编译,此时会生成相对应的pb.cc文件和pb.h文件。

#推荐这种顺序
protoc person.proto --cpp_out=./  #末尾的'./'表示生成的cc、h文件存放在当前目录(可调整)。
protoc person.proto --python_out=./   #我们也可以生成python之类的编译文件

#当然调换一下参数顺序也是一样的
protoc --cpp_out=./ person.proto
protoc --python_out=./ person.proto

#另外也是可以一次性编很多文件的,如下:
protoc com.tencent.*.proto --python_out=.
protoc com.tencent.epc.qidian.cc*.proto --python_out=.

效果如下:

3、python对序列化的字串反序列化为protobuf结构

注:其中用到的im_msg_body_pb2就是im_msg_body.proto文件经过编译后生成的python库文件。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import im_msg_body_pb2

row_msg_body = b"\n\271\001\n!\010\000\020\223\203\321\363\005\030\343\337\232\334\007 \000(\n0\0008\206\001@\002J\006\345\256\213\344\275\223\022^\312\001[\nY\010\003\022\004\010\000\020\001(\0030\242\333\255\311\005H\225\340\215\320\n\212\001\017861684676539011\352\001.webim_2852155980_861684676539011_1584676769010\0224\n2\n0\345\275\223\346\227\266\347\273\231\346\210\221\344\273\213\347\273\215\347\232\204\346\227\266\345\200\231\350\257\264\344\270\200\346\254\241\346\200\247\351\200\200\345\256\214\345\225\212";

print("----------实例结构对象,对原生字串反序列化-----------")
msgbody = im_msg_body_pb2.MsgBody()
msgbody.ParseFromString(row_msg_body)
print(msgbody)


print("---------------母结构赋值子结构----------------------")
rich_text = im_msg_body_pb2.RichText()
rich_text = msgbody.rich_text;
print(rich_text)

print("----------取repeated对象(Elem为repeated)------------")
elem = im_msg_body_pb2.Elem();
elem = msgbody.rich_text.elems[1]
print(elem)

print("-----------下面打印的就是汉字了----------------")
text = im_msg_body_pb2.Text();
text = msgbody.rich_text.elems[1].text
print(text.str)

 

 

4、数据读写之write.cc写数据到本地硬盘

#include
#include

#include "person.pb.h"
using namespace std;
using namespace tencent;

int main()
{
    Person p1;

    p1.set_name("shuozhuo");
    p1.set_age(22);
    p1.set_phnum(17367078333);

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

    if (!p1.SerializeToOstream(&output)){
        cerr << "Failed to write msg."<

执行如下语句进行编译,生成可执行文件write,并执行之:

g++ person.pb.h person.pb.cc write.cc -o write `pkg-config --cflags --libs protobuf` -lpthread

注意:(1)上述指令中的“`”并不是单引号,而是键盘上按键“1”左边的那个按键对应的符号。

(2)关于pkg_config还是值得继续学习的。

(3)编译 时添加 -lprotobuf库到编译选项中。

5、编写read.cc从本地读取数据

#include
#include
#include "person.pb.h"

using namespace std;
using namespace tencent;

void PrintInfo(const Person &p1){
    cout << "The information is:" << endl;
    cout << "    name:" <<  p1.name() <

编译语句如下,完成后生成可执行文件read:

g++ person.pb.h person.pb.cc read.cc -o read `pkg-config --cflags --libs protobuf` -lpthread

执行read,效果如下:

linux环境下protobuf的安装与使用_第1张图片

 

三、protobuf学习

更多学习,参见 protobuf使用手册

 

 

 

 

 

你可能感兴趣的:(协议)