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.gzwget https://github.com/protocolbuffers/protobuf/releases/download/v3.6.1/protoc-3.6.1-linux-x86_64.zipgit 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 -j8make 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
https://github.com/549jest/LibTransAndUse/tree/master/Protobuf3.6.1/useDemo
更多protobuf的简介、语法、使用、实现原理请移步。https://blog.csdn.net/asmartkiller/article/details/89454276