网站首页 > 技术教程 正文
什么是protobuf-c
之前的文章:Protobuf:一种更小、更快、更高效的协议 详细介绍了protobuf及protobuf-c。这里再简单提一下:
Protocol Buffers,是Google公司开发的一种数据格式,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。protobuf支持一些主流的语言,唯独没有支持C,所以诞生了第三方的protobuf-c。
之前文章介绍了protobuf、protobuf-c在PC平台上的安装及使用,本篇笔记我们来把它用在我们的嵌入式ARM平台。
交叉编译protobuf-c
之前的文章中我们已经把protobuf、protobuf-c安装在我们的PC环境中了:
我们简单回顾一下我们上一篇文章的大致内容:
从中我们知道,这里的protobuf的主要作用是生成了protoc工具,而protoc工具的作用是把.proto文件生成对应的C源、头文件,这个过程是与平台无关的,所以这里我们可以接着用。而protobuf-c生成了编译需要用到的动态库,此处我们需要编译ARM架构的动态库。即我们本篇笔记需要做的事情是:
(1)交叉编译protobuf-c
首先在protobuf-c目录下使用make clean命令清除我们之前编译得到的东西:
输入如下命令生成交叉编译的Makefile文件:
./configure --host=arm-linux-gnueabihf CC=/home/book/ToolChain/gcc-arm-linux-gnueabihf-6.2.1/bin/arm-linux-gnueabihf-gcc CXX=/home/book/ToolChain/gcc-arm-linux-gnueabihf-6.2.1/bin/arm-linux-gnueabihf-g++ --disable-protoc --prefix=$PWD/tmp
这个命令似乎很长,但并不难,只是加了几个配置参数。这些配置参数怎么看?我们可以输入./configure --help命令来查看支持的配置:
下面我们依次来分析上面那个很长的命令:
- --host=arm-linux-gnueabihf:表明了我们最终可执行文件运行的环境。
- CC=/home/book/ToolChain/gcc-arm-linux-gnueabihf-6.2.1/bin/arm-linux-gnueabihf-gcc:这是指定我们的交叉编译工具arm-linux-gnueabihf-gcc,这里直接给出绝对路径。
- CXX=/home/book/ToolChain/gcc-arm-linux-gnueabihf-6.2.1/bin/arm-linux-gnueabihf-g++:这是指定我们的交叉编译工具arm-linux-gnueabihf-g++,这里直接给出绝对路径。
- --disable-protoc:不使用protoc,前面我们也说了protoc工具把.proto文件生成对应的C源、头文件的过程是与平台无关的,所以这里不需要使用,除非我们想在我们的开发板上使用protoc,但这反而增加麻烦,不推荐直接在开发板上用。
- --prefix=$PWD/tmp:指定安装的路径。表明安装路径在当前路径下的tmp文件夹中。
执行完这个命令之后就得到了交叉编译的Makefile文件,然后依次输入如下命令进行编译、安装:
make
make install
此时就在当前目录的tmp文件夹下生成了arm版本的相关库文件:
其中我们比较重要的就是libprotobuf-c.so这个动态库了,我们可以使用file或者readelf工具查看其是不是arm格式的:
很显然,这就是我们ARM平台的动态库。
下面开始我们的demo演示:
(2)protobuf-c实例演示
我们自定义一个.proto来创建我们的协议数据,然后使用protoc-c工具编译生成C代码,有两个文件:一个头文件、一个源文件。
例如我们创建一个student.proto文件:
syntax = "proto2";
message Student
{
required string name = 1;
required uint32 num = 2;
required uint32 c_score = 3;
}
使用protoc-c工具工具编译student.proto文件:
protoc --c_out=. student.proto
编写我们的student.c测试demo:
/* 微信公众号:嵌入式大杂烩 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "student.pb-c.h"
int main(void)
{
Student pack_stu = {0};
uint8_t buffer[512] = {0};
Student *unpack_stu = NULL;
size_t len = 0;
student__init(&pack_stu);
/* 组包 */
pack_stu.name = "ZhengN";
pack_stu.num = 88;
pack_stu.c_score = 90;
len = student__pack(&pack_stu, buffer);
printf("len = %ld\n",len);
/* 解包 */
unpack_stu = student__unpack(NULL, len, buffer);
printf("unpack_stu.name = %s\n", unpack_stu->name);
printf("unpack_stu.num = %d\n", unpack_stu->num);
printf("unpack_stu.c_score = %d\n", unpack_stu->c_score);
student__free_unpacked(unpack_stu, NULL);
return 0;
}
demo很简单,组包就是构造一个协议数据结构体,调用pack组包接口往buffer中扔数据;解包正好是反过来,从buffer中拿数据放到结构体里。
此时我们工程的文件有:
交叉编译:
arm-linux-gnueabihf-gcc student.c student.pb-c.c -o student -I /home/book/git_clone/protobuf-c/tmp/include -L /home/book/git_clone/protobuf-c/tmp/lib -lprotobuf-c
这个命令似乎也很长,其实也很简单:
- arm-linux-gnueabihf-gcc:交叉编译器。
- student.c student.pb-c.c:输入的源文件。
- student:生成的可执行文件。
- -I /home/book/git_clone/protobuf-c/tmp/include:指定头文件路径。
- -L /home/book/git_clone/protobuf-c/tmp/lib:指定库路径。
- -lprotobuf-c:链接动态库libprotobuf-c.so。
这里需要重点提的就是我们可以把我们上面编译得到的tmp/include里的文件复制到我们交叉编译器头文件搜索路径下、把tmp/lib里的文件复制到交叉编译器库文件搜索路径下,这样我们就不需要指定这么长的一串路径了。
但是这里我为了保持我的交叉编译器的一个原始性,我就不往里加东西了。关于这些链接、动态库更详细的内容可以阅读往期文章:静态链接与动态链接(Linux) 、静态链接与动态链接
编译没问题的话就可以生成我们的可执行文件student:
同样的,我们可以看一下student可执行文件的运行环境:
可见,是可运行在我们的arm开发板的。
下面把student拷贝到我们的开发板上运行,我这里用的是韦东山老师的IMX6ULL开发板。
运行出现如下错误:
这是因为不能找到共享库文件libprotobuf-c.so1,加载失败,这个问题我们已经在静态链接与动态链接(Linux) 一文中做了详细解释。
解决方法有两种:第一种就是把这个库文件拷贝至系统库默认搜索路径下;第一种就是把当前路径增加为动态库的搜索路径。
这里我们选择第二种方法:我们把libprotobuf-c.so、libprotobuf-c.so1也传到板子上,放在student同目录下。然后输入如下命令把当前路径增加为动态库的搜索路径:
export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH
然后运行:
运行成功!
以上就是咱们介绍的protobuf-c在嵌入式Linux平台上的使用(如果是正在学单片机的朋友,也可以尝试着移植使用。),如有错误,欢迎指出,谢谢。另外,
按照以上两篇文章的步骤,大概率是可以成功的,关键是有耐心。
心得分享:在Linux的学习中,很多时候会被开发环境阻碍我们。常常按照别人的方法、步骤来做,却做不出来,很容易心态蹦,这都是很正常的。因为环境不同,有时候还需要各种依赖。但我们要有足够的耐心,见招拆招!
在此之前,我也遇到了很多问题,也搜索了很多博客文章,要么行不通,要么写得太乱。所以趁此学习、写一篇。
如果文章对你有帮助,麻烦帮忙转发支持,谢谢大家!
1024G 嵌入式资源大放送!包括但不限于C/C++、单片机、Linux等。私信回复1024,即可免费获取!
猜你喜欢
- 2024-10-11 Java面试题总结 java面试题整理
- 2024-10-11 全志V3S开发板驱动示例(linux demo驱动开发)
- 2024-10-11 使用Visual Studio Code编写调试C语言
- 2024-10-11 C++编程知识:教你手写C++内存池 c++内存池实现
- 2024-10-11 大华报警主机的常开、常闭接线方式与协议配置
- 2024-10-11 60秒一口Python:147个demo,助你从零基础步步进阶编程高手
- 2024-10-11 八周年了!小岛秀夫发推纪念经典恐怖佳作《P.T.》
- 2024-10-11 互动电影三部曲登陆Steam,《底特律变人》Demo免费试玩中
- 2024-10-11 亲爱的:KK战队如果是一个男团,你觉得谁是C位,网友们都说是他
- 2024-10-11 Istio 在阿里云容器服务的部署及流量治理实践
你 发表评论:
欢迎- 05-14喜报!双色球5注824万头奖花落辽宁等地,开奖情况一览
- 05-14双色球新一期前瞻:红球蓝球走势深度剖析,精选号码提前看
- 05-1449倍、33倍、30倍、15倍!双色球第25053期开奖:多张倍投票集结
- 05-14双色球25054期:红球:04、05、15、18、29、33 蓝球:05、08
- 05-14厉害了!495倍独蓝票、万元独蓝票双双报喜!双色球第25053期开奖
- 05-14双色球25054期!龙头02凤尾31,独蓝14稳中,连号20-21围剿奖池!
- 05-14双色球25054期参考:蓝球侧重选2路蓝,红球依然三金胆、重号先
- 05-14双色球25054期:独蓝04,头01尾30,连号15-16,6+1精选
- 最近发表
-
- 喜报!双色球5注824万头奖花落辽宁等地,开奖情况一览
- 双色球新一期前瞻:红球蓝球走势深度剖析,精选号码提前看
- 49倍、33倍、30倍、15倍!双色球第25053期开奖:多张倍投票集结
- 双色球25054期:红球:04、05、15、18、29、33 蓝球:05、08
- 厉害了!495倍独蓝票、万元独蓝票双双报喜!双色球第25053期开奖
- 双色球25054期!龙头02凤尾31,独蓝14稳中,连号20-21围剿奖池!
- 双色球25054期参考:蓝球侧重选2路蓝,红球依然三金胆、重号先
- 双色球25054期:独蓝04,头01尾30,连号15-16,6+1精选
- 一号之差!井喷1416注,5注一等奖,100注二等,双色球25053开奖
- 双色球25054期:1、5尾,头单,尾双,斜连三码,胆11、12、27
- 标签列表
-
- sd分区 (65)
- raid5数据恢复 (81)
- 地址转换 (73)
- 手机存储卡根目录 (55)
- tcp端口 (74)
- project server (59)
- 双击ctrl (55)
- 鼠标 单击变双击 (67)
- debugview (59)
- 字符动画 (65)
- flushdns (57)
- ps复制快捷键 (57)
- 清除系统垃圾代码 (58)
- web服务器的架设 (67)
- 16进制转换 (69)
- xclient (55)
- ps源文件 (67)
- filezilla server (59)
- 句柄无效 (56)
- word页眉页脚设置 (59)
- ansys实例 (56)
- 6 1 3固件 (59)
- sqlserver2000挂起 (59)
- vm虚拟主机 (55)
- config (61)
本文暂时没有评论,来添加一个吧(●'◡'●)