Protobuf安装|编译|使用

Protobuf安装|编译|使用,第1张

Linux编译安装protocal-3.6.1

https://github.com/protocolbuffers/protobuf/releases/tag/v3.6.1

test.cc

protoc test.proto --cpp_out=.

此时当前目录将档凳生成两个文件test.pb.cc test.pb.h

-I:指定protobuf的头文件

-L: 指定protobuf的库文件

*可能会遇到以下报错

/usr/bin/ld: cannot find -lprotobuff

collect2: error: ld returned 1 exit status

这是因为gcc 编译器找不到protobuf.so库文雀虚件,因为在usr/local/lib下的protobuf.so不能被gcc找到。解决方法有两种:

a. export LD_LIBRARY_PATH=/usr/local/lib (这种方法临时生效,重启就不生效了)

b. 在/etc/ld.so.conf 文件里面添加路径 /usr/local/lib ,因为linux系统运行库会读取这里的目录寻行岁旅找so,之后ldconfig

这一步结束编译出可执行文件a.out

https://github.com/ttroy50/cmake-examples

在windows下使用protobuf,编译成dll,在使用中提示下面错误( unresolved external symbol 

?empty_string_once_init_@internal@protobuf@google@@3HA (int google::protobuf::internal::empty_string_once_init_),

?empty_string_@internal@protobuf@google@@3PBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@B (class std::basic_string,class std::allocator>const * const google::protobuf::internal::empty_string_)

提示这两个函数,而通过用dumpbin 查看libprotobufd.dll,其中导出了这两个函数,最后在这里找到

答案

需要在引用这个dll的工程中加入宏 PROTOBUF_USE_DLLS,通过搜索protobuf工程,发现定义这个宏之后,添加这个宏之后,会有下面的宏定义:

#define LIBPROTOBUF_EXPORT__declspec(dllimport)

有可能在加入pb之后,你的工程出现数百个未定义的类型,而明显在你的项目中,这些都是有定义的,这个时候,你可以考虑把斗庆弊pb消息的头文件添加到其他头文件之前

默认生成的xxx.pb.h,xxx.pb.cc的类在windows下都是没有_dllexport符号修饰,所以不可以在生成的dll中导出使用,可以通过 `protoc --cpp_out=dllexport_decl=MY_EXPORT_MACRO:path/to/output/dir myproto.proto`来实现为所有的类添加`MY_EXPORT_MACRO`修空族饰差源符。然后在另外一个h文件中定义`MY_EXPORT_MACRO`宏,然后在所有的头文件中包含它

在网络通信中,我们亮派经常需要通过一种约定俗称的方式来进行数据交互。在这中间,有很多如xml,json等等很常见的数据格式。

xml是一种标签语言,通过<tag>content</tag>来描升键并述数据内容,出现时间最早,应用最广泛,但是传输效率低。

json作为一种轻量级的数据交换格式,其无效的字符数远远低于xml,且原生被js支持,故经常出现在前端请求中以及app与服务器的数据交互。

protobuf是google的一种数据交换格式,相比于其他的几种交互方式,其优势在于数据的重编码,在传输时会将其编译为二进制数吵迹据流,而当需要使用时再进行反序列化。

protobuf支持几乎绝大多数的语言。

通过proto文件,我们可以了解到一个数据的详细类型。

在官方示例中可以看到一个数据类型的声明方法:message 对象 {}。在{}中则是添加相应的字段描述,每个字段描述如下

数据类型为protobuf声明的数据类型,每个类型在不同的语言上均有特定的映射。

或可以是一个声明的自定义数据类型。

声明完成后通过protoc编译为特定语言的头文件。

引入头文件后 首先声明一个对象

通过person.xxx可以直接对某个字段进行赋值

在序列化过程中有可能因为required未被赋值而导致序列化失败

序列化成功后便可以将二进制数据发送出去

收到对应的数据后,我们需要从二进制数据中获取对应的对象

person = addressbook_pb2.Person()

person.ParseFromString(pb_bin)


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/tougao/12198973.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存