开发protobuf扩展的一些笔记

来源:互联网 发布:社交关系网络量化建模 编辑:程序博客网 时间:2024/06/13 02:15

一个需求要接入公司内部的一个基于protobuf协议的接口,protobuf的库文件都是proto编译器生成的cpp文件。要编译成php扩展的话,需要c/c++混编,这里记录一下。

1、升级一下安装的protobuf,貌似C1的机器上的protobuf都是2.4.0的,当编译高级的一些语法的proto文件的时候都会报错的,升级到2.5.0以上的版本好些。

2、proto编译器会根据proto文件生成相关的cc文件,里面包含着消息体的一些操作函数,比如解包,造包,序列化,反序列化之类的函数,反正很丰富。你需要把他们编译进你的php扩展里面,所以你得自己编译成静态库文件(.a文件),记得要加-fPIC选项,否则会报:relocation R_X86_64_32 against `.rodata’ can not be used when making a shared object; recompile with -fPIC。

3、要用到pb的内置api,上一步咱们生成的cc文件里面有些方法和函数是protobuf的全局函数,需要这个protobuf.a文件的支持。这时候你需要把protobuf的静态库一起编译进去,通常是protobuf.a文件(好奇为啥不是libprotobuf.a),所以在编译整个php扩展的时候,会报出这个错误:could not read symbols: Bad value,好吧,应该是在编译要链接的静态库的时候没加上-fPIC选项。需要重新编译一下,但是看了一下protobuf的Makefile,大的吓人,改起来岂不是很坑爹。所以直接从configure文件改好了,在用configure生成makefile的时候直接加上选项–enable-static=yes就好了。

4、因为涉及到c/c++混编,所以需要指定一下confg.m4的一些参数。
PHP_REQUIRE_CXX() :次扩展要用到c++.
PHP_ADD_LIBRARY(stdc++, 1, EXTRA_LDFLAGS) :因为咱们的php扩展是cpp文件,而php的扩展makefile文件指定使用的是gcc,用gcc去编译cpp文件,(编译阶段的gcc和g++都是等价的,所以cpp文件在这里还是由gcc去编译,但是链接就不一样了),会因为gcc无法直接链接cpp库文件而导致错误,所以需指定g++来链接,所以就得指定stdc++了。
PHP_ADD_LIBRARY_WITH_PATH : 指定你库文件的目录了,相当于直接编译的时候加上-iXX.a -I/usr/local/include/XXX之类的了。
至于需不需要在cpp文件的部分加上extern “c” ,我觉得无所谓啊,反正编译阶段gcc/g++的行为都一致的,只是链接方式不一样而已。

然后就开始编译吧。

0 0
原创粉丝点击