设为首页 收藏本站
查看: 623|回复: 0

[经验分享] python调用动态链接库传送protobuf数据。

[复制链接]

尚未签到

发表于 2018-8-5 13:40:00 | 显示全部楼层 |阅读模式
  什么是protobuf
  protobuf是Google提供的一个开源序列化框架,类似于XML,JSON这样的数据表示语言,其最大的特点是基于二进制,因此比传统的XML表示高效短小得多。开发者定义类似于结构体的message,通过protobuf的工具将定义好的格式传送给protobuf的接收工具,接收工具会自动产生类,需要传输的时候直接导入这个类,将关键字段填充,通过序列化函数,将其序列化,接收端将其反序列化,实现数据传输。protobuf支持c++,java,python。详细信息见参考文档。
  protobuf的格式定义,可以看文档,这里举两个简单实用的例子:
  


  • message User {
  •   required string username = 1;
  •   required string password = 2
  •   required int32 age = 3;
  •   optional string email = 4;
  •   }

  

  protobuf作为一种数据表示语言,有自己的类型,如代码中写的string,int32,等等,required,optional代表这个字段是否是必填,必填写required,不必填充写optional。后面的1,2,3是序号,不是这个字段的值,必填字段是要在程序中进行填充,或者设置默认值。关于protobuf的类型和格式可以看Google Language Guide,如果想定义一个User数组进行传输,可以这样定义(注意关键字repreated):
  


  • message User {
  •   required string username = 1;
  •   required string password = 2;
  •   required int32 age = 3;
  •   optional string email = 4;
  •   }

  • message Users {
  •   repeated User user = 1;
  •   }

  

  在定义好格式之后(message文件以.proto结尾),我们可以安装protobuf的linux下的message生成工具,具体可以去Google官方下载,这是个开源项目,安装的时候还是那几步,./configure,make,make install,很简单,前提需要gcc编译器。然后安装一个protobuf的类库,这里我以python2.5为例,需要安装类库,protobuf-2.3.0-py2.5.egg,egg文件类似于c++中的.so或者是java中的jar文件,是一个库文件,提供调用,安装egg文件最简单的方法是安装easy_install,如果你不想安也可以,指定egg文件的路径,但是这样做会有些风险,因为加载egg文件还需要一个python的库setuptools-0.6c9-py2.5.egg,你可以这么干:
  export PYTHONPATH=$SRC_DIR/protobuf-2.3.0-py2.5.egg:$SRC_DIR/setuptools-0.6c9-py2.5.egg
  这么干的目的是把这些库文件导入python的sys.path路径中,加载的时候也能加载到,这样你在程序里直接import google.protobuf,或者导入其他protobuf的库 肯定不会报错,c++和java就不细说了,大同小异。
  安装完成后,执行 protoc -I=$SRC_DIR --python_out=$DST_DIR $SRC_DIR/User.proto 如果,没提示错误的话会在输出目录下生成 XXX_pb2.py文件(我上面定义的会生成User_pb2.py),这个就是生成的类,用的时候直接引入就可以(放在一个目录下,或者导入sys.path)。
  关于python调用动态链接库,python提供了一个库,ctypes,这个库2.4以及2.4之前都没有,用的时候注意版本,调用如下:
  


  • from ctypes import *
  • import User_pb2


  • libs = CDLL("./libs.so")
  • libs.Init()
  • user = User_pb2.User() #类似于构造方法
  • user.username = 'zhangpeng'
  • user.password = 'xxxxxxxxx'
  • user.age = 23
  • sContent = user.SerializeToString() #序列化方法
  • libs.Send(c_char_p(sContent), c_uint(len(sContent)))
  • libs.IPCExit()
  我只是粗略的写一下,大家肯定一看就明白。如果传送protobuf数组,就可以这样写:  

  

  

  


  • from ctypes import *
  • import Users_pb2


  • libs = CDLL("./libs.so")
  • libs.Init()
  • users = User_pb2.Users() #类似于构造方法
  • user = users.add()
  • user.username = 'zhangpeng'
  • user.password = 'xxxxxxxxx'
  • user.age = 23
  • sContent = users.SerializeToString() #序列化方法
  • libs.Send(c_char_(sContent), c_uint(len(sContent)))
  • libs.IPCExit()
  

  就这么简单,加一个add方法,注意User 和Users的区别,
  结束语:这个东西本来是要在c++中实现的,但是涉及的东西很多,改起来相对较麻烦,而且有风险,改成用py实现了,但是c肯定要比python的序列化效率高,个人认为python更像一支粘合剂,很好用。有什么问题直接指出,望赐教。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-547060-1-1.html 上篇帖子: python子进程模块subprocess详解 下篇帖子: python 更新svn 并复制到其他目录
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表