1.編譯環境准備,在Ubuntu下安裝好autoconf、automake、libtool、make、g++、unzip,並准備好交叉工具鏈。
執行命令:
sudo apt-get install autoconf automake libtool curl make g++ unzip
2.下載c++版本的protobuf
網站:https://github.com/protocolbuffers/protobuf/releases
下載protobuf-cpp-[VERSION].tar.gz以及相應版本protoc工具protoc-[VERSION]-linux-x86_64.zip(我的UBuntu是64位的)
可以用瀏覽器下載、也可以用wget下載,還可以用git clone下載protobuf源碼。
wget 下載,例如:
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protobuf-cpp-3.6.1.tar.gz
wget https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protoc-3.6.1-linux-x86_64.zip
git clone下載,例如: git clone https://github.com/protocolbuffers/protobuf.git
cd protobuf git submodule update --init --recursive ./autogen.sh
3.交叉編譯成庫
先解壓 tar -xvf protobuf-cpp-3.6.1.tar.gz
進入 protobuf-3.6.1目錄,執行命令
./configure --host=arm-linux --prefix=xxx/xxx/protobuf3.6.1-arm CC=xxx/xxx/arm-linux-gcc CXX=xxx/xxx/arm-linux-g++ --with-protoc=../protoc-3.6.1/bin/protoc
看一下自己ubuntu支持最大線程數
cat /proc/cpuinfo | grep "processor" | wc -l
我輸出的是8
make -j8
make check
解壓protoc工具
mkdir protoc-3.6.1 unzip protoc-3.6.1-linux-x86_64.zip -d protoc-3.6.1
4.簡單使用protobuf
(1)編寫proto文件MyTest.proto如下:
syntax="proto3"; package MyTest; message TestMessage{ uint64 id=1; uint32 state=2; string name=3; } message AllMessage{ uint64 all_id=1; uint32 all_state=2; TestMessage testmsg=3; }
(2)使用解壓好的protoc工具生成.cc和.h文件,執行命令
xxx/xxx/protoc -I=./ --cpp_out=xxx/xxx xxx/xxx/MyTest.proto -I Specify the directory in which to search for imports. --cpp_out Generate C++ header and source xxx/xxx/MyTest.proto target which will be Generate to C++ header and source
(3)簡單使用protobuf進行序列化與反序列化示例
#include <iostream> #include "MyTest.pb.h" int MakeData(char *outPutData) { MyTest::AllMessage allmsg; allmsg.set_all_id(123); allmsg.set_all_state(234); #if 0 /*不能用靜態分配的TestMessage類,需要用new分配*/ MyTest::TestMessage testmsg; testmsg.set_id(345); testmsg.set_state(567); testmsg.set_name("HelloWorld"); allmsg.set_allocated_testmsg(&testmsg); #endif MyTest::TestMessage *testmsg=new MyTest::TestMessage; testmsg->set_id(345); testmsg->set_state(567); testmsg->set_name("HelloWorld"); allmsg.set_allocated_testmsg(testmsg); int len=allmsg.ByteSize(); if(allmsg.SerializePartialToArray(outPutData,len)) return len; else return -1; } void DeData(char *inputData,int len) { MyTest::AllMessage allmsg; if(allmsg.ParseFromArray(inputData,len)) { std::cout<<"all_id="<<allmsg.all_id()<<std::endl; std::cout<<"all_state="<<allmsg.all_state()<<std::endl; std::cout<<"testmsg.id="<<allmsg.testmsg().id()<<std::endl; std::cout<<"testmsg.state="<<allmsg.testmsg().state()<<std::endl; std::cout<<"testmsg.name="<<allmsg.testmsg().name()<<std::endl; } else { std::cout<<"parse data is error"<<std::endl; } } int main() { char buf[1024]; int len=MakeData(buf); if (len>0) { DeData(buf,len); } return 0; }
輸出:
源碼位置:https://github.com/jest549/LibTransAndUse/tree/master/Protobuf3.6.1/useDemo
更多protobuf的簡介、語法、使用、實現原理請移步。https://blog.csdn.net/asmartkiller/article/details/89454276