protobuf-c的使用(二)使用

发布时间:2020-07-23 17:14:22 作者:kid2412
来源:网络 阅读:5242

上一篇介绍了protobuf-c的构建。接下来介绍一下protobuf-c的使用。protobuf最核心的就是proto文件,其次通过protobuf-c编译proto文件生成供c语言调用的库文件和头文件。下面逐一说明一下proto文件的定义、protobuf-c编译以及c语言如何使用protobuf。

一、proto文件结构

protobuf以消息Message为主要结构,消息中包含具体的字段,字段定义主要以required(必填字段)、optional(可选字段)、repeated(可重复字段)为主,包含了各大编程语言的基本数据类型、引用类型等。具体定义参考如下:

.proto类型描述packc/c++类型
bool布尔类型pack(1)bool
double64位浮点类型pack(N)double
float32位浮点类型pack(N)float
int3232位整数类型pack(N)int
int6464位整数类型pack(N)__int64
uint32无符号32位整数类型pack(N)unsigned int
uint64无符号64位整数类型pack(N)unsigned __int64
sint3232位整数类型,使用可变长编码方式。有符号的整型值。编码时比通常的int32高效。pack(N)int
sint6464位整数类型 ,使用可变长编码方式。有符号的整型值。编码时比通常的int64高效。pack(1)__int64
fixed3232位无符号整数类型 ,总是4个字节。如果数值总是比总是比228大的话,这个类型会比uint32高效。pack(4)bool
fixed6464位无符号整数类型,总是8个字节。如果数值总是比总是比256大的话,这个类型会比uint64高效。pack(8)bool
sfixed3232位整数类型,总是4个字节。pack(4)bool
sfixed6464位整数类型,总是8个字节。pack(8)bool
string字符串类型pack(N)char*/char[]/std:string
bytes一个字符串必须是UTF-8编码或者7-bit ASCII编码的文本。pack(N)char*/char[]/std:string
enum用户自定义枚举类型pack(N)与 uint32相同bool
message用户自定义的消息类型pack(N)struct/class

N 表示打包的字节并不是固定。而是根据数据的大小或者长度打包。

二、protobuf-c编译proto文件

编译命令:

 protoc-c --c_cout=. .proto文件 -lprotobuf-c

举个栗子: 
定义消息Message Command(命令),其中包含字段:

.proto文件如下(Command.proto):

message Command{
        required sint64 code = 1; //指令代码
        required sint32 type = 2; //指令类型 0 查询 1 读写 2 调用执行
        required string module = 3; //调用模块名
        required string func = 4; //调用函数名
        repeated string params = 5; //函数参数}

message CommandResponse{
        required sint32 code = 1; //返回代码 0 成功 1 失败
        optional string msg = 2; //返回消息 失败消息或成功消息
        required sint32 version = 3; //接口版本
        repeated Command data = 4; //真正的数据字段}1234567891011121314

执行命令:

protoc-c --c_out=. Command.proto -lprotobuf-c

protobuf-c的使用(二)使用

可以看到生成了Command.pb-c.c和Command.pb-c.h的c语言源文件和头文件。

三、c语言中使用protobuf

接下来尝试调用上面生成的c文件。protobuf-c使用pack和unpack方法做序列化和反序列化操作。

在使用packed之前需要使用__INIT函数创建PB对象,然后为对象中字段逐一赋值。

    CommandResponse response=COMMAND_RESPONSE__INIT;

这里需要注意response中包含的Command,也需要使用__INIT函数进行初始化并赋值。

    Command command=COMMAND__INIT;

在逐一赋值后,我们需要分配一个buffer用于保存序列化字节,在对buffer分配空间时,可以使用__get_packed_size函数获取PB结构体的大小作为分配空间的大小。

    size_t size=command_response__get_packed_size(&response);

接下来使用__pack函数执行序列化操作。

    command_response__pack(&response,buf);

反序列化操作可直接使用__unpack函数。得到反序列化后的对象指针,通过指针可直接访问PB中的字段。

    CommandResponse *response=
    command_response__unpack(NULL,size,buf);

在对PB访问完成后,需要通过__free_unpacked来释放反序列化的内存空间。

  command_response__free_unpacked(response, NULL);

具体例子可参考protobuf-c的github wiki:https://github.com/protobuf-c/protobuf-c/wiki/Examples


推荐阅读:
  1. 二、logstash原理和使用
  2. UITabBarController的基本原理及使用(二)

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

protobuf pb buf

上一篇:OpenTsdb官方文档----日期和时间

下一篇:如何实现PHP只保留数字

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》