摘要:
记录编译并使用protobuf完成c++序列化
编译:
tar -xzvf protobuf-all-3.19.4.tar.gz
cd protobuf-3.19.4/
./configure
make all
make install
默认安装的protobuf库的位置:
/usr/local/lib
编译时依赖protobuf库
-L/usr/local/lib -lprotobuf
运行程序时需要提前指定动态库的查找位置:
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
使用protobuf:
文件目录结构:
.
├── agent
├── build.sh
├── Makefile
├── run_proto.sh
├── src
│ ├── base
│ ├── config
│ ├── http
│ │ └── httplib.h
│ ├── proc
│ ├── proto
│ │ ├──
│ │ ├── hello.pb.h
│ │ └── hello.proto
│ ├── router
│ │ ├──
│ │ ├── router.h
│ │ ├── router_
│ │ └── router_test.h
│ └── server
│ ├──
│ └── server.h
└── utest
└── ut_testData.sh
9 directories, 15 files
hello.proto:
syntax = "proto2";
message helloworld
{
required int32 id=1;
optional string str=2;
enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}
message PhoneNumber {
optional string number = 1;
optional PhoneType type = 2;
}
repeated PhoneNumber phones = 4;
}
使用protoc生成c++协议文件:
protoc --cpp_out=. ./src/proto/hello.proto
- --cpp_out: 生成的cpp文件位置, 相对于后边跟随的proto位置
- 后边跟随指定的proto文件
测试proto的代码:
#include <iostream>
#include "../src/proto/hello.pb.h"
bool writeBuf(string file_path)
{
helloworld msg1; // 包名::Message名
helloworld::PhoneNumber *phone; // 注意嵌套Message使用指针
msg1.set_id(100);
msg1.set_str("200");
phone = msg1.add_phones();
phone->set_number("12345");
phone->set_type(helloworld_PhoneType_HOME); // 注意Enum的调用方式(所有的默认值相当于C++中的Const对象, 所以直接使用类调用)
// Write the new address book back to disk.
fstream output(file_path, ios::out | ios::trunc | ios::binary);
if (!msg1.SerializeToOstream(&output)) {
std::cerr << "Failed to write msg." << std::endl;
return false;
}
return true;
}
// 输出数据
void ListMsg(const helloworld & msg) {
cout << msg.id() << std::endl;
cout << msg.str() << std::endl;
for (int i =0; i<msg.phones_size(); i++)
{
// 注意此时调用嵌套类中的值不是用的指针方式.
cout << msg.phones(i).number() << std::endl;
}
}
// 读取文件,写入到protobuf生成的类中
bool readBuf(string file_path)
{
helloworld msg1;
{
fstream input(file_path, ios::in | ios::binary);
if (!msg1.ParseFromIstream(&input)) {
std::cerr << "Failed to parse address book." << std::endl;
return -1;
}
}
ListMsg(msg1);
}
int main()
{
string path = "../test.log";
writeBuf(path);
readBuf(path);
return 0;
}
root@localhost:~/work/ndb-influxdb-instance/src/agent# ldd agent
linux-vdso.so.1 (0x00007ffe49789000)
libprotobuf.so.30 => /usr/local/lib/libprotobuf.so.30 (0x00007f230780a000)
libz.so.1 => /lib64/libz.so.1 (0x00007f23075f3000)
libbrotlicommon.so.1 => /lib64/libbrotlicommon.so.1 (0x00007f23073d2000)
libbrotlienc.so.1 => /lib64/libbrotlienc.so.1 (0x00007f2307146000)
libbrotlidec.so.1 => /lib64/libbrotlidec.so.1 (0x00007f2306f39000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f2306ba4000)
libm.so.6 => /lib64/libm.so.6 (0x00007f2306822000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f230660a000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f23063ea000)
libc.so.6 => /lib64/libc.so.6 (0x00007f2306025000)
/lib64/ld-linux-x86-64.so.2 (0x00007f2307cb0000)