PHP中调用C/C++制作的动态链接库的教程


Posted in PHP onMarch 10, 2016

一般而言,php速度已经比较快,但是,对于一些较高级开发者而言,如果想要追求更快的速度,那毫无疑问可以通过自己写c代码,并编译为动态链接库(常为.so文件),然后php通过创建一个新的扩展(extension),并在扩展里调用该.so文件,同时对外暴露出php函数接口。
在实际使用中,只要调用该函数接口,即可使用底层更快速的c函数服务。

一、动态链接库(shared)

动态链接库的文件名后缀通常是 ".so"。在Windows系统中,其文件名后缀是".dll"。

程序如果是和动态连接库进行链接(link),程序运行时需要能够找到相应的动态链接库文件。

使用动态链接库存编译的程序在运行时要求用户的机器上必需也安装了相应的动态链接库文件,这些库文件需要放置在特定的目录,以让程序能够加载这些库。

虽然这似乎没有使用静态链接库的程序使用方便,但却减少了程序的大小。对于那些会被很多程序使用到的库,使用动态链接的好处就更加明显了。

动态链接库的制作:

gcc -shared -fPIC -o libmylib.so mylib.c  ; # 编译成为shared library

选项-fPIC在AMD64上是必须的,其它平台是则不是必要选项。

包含静态链接库到动态链接库中

编译动态链接库时,如果需要链接静态库,并把链接库的内容包含到要编译的动态库中,可以使用选项-Wl,--whole-archive。

例如:

gcc -shared -o libmylib.so -Wl,--whole-archive libmylib.a \
  -Wl,--no-whole-archive libother.a

上面的-Wl表示传递给linker(链接器)。

二、调用动态C/C++链接库
下面,本文的开发环境背景是CentOS release 6.5 。为了能够调用c库,我们的php 5.6.9,apache 2.4均是下载源码并编译的,不可直接通过yum安装!请注意。至于php和apache的源码编译本文不提,只要注意在configure打开合适开关即可。

具体步骤如下:
将共享库.so添加入系统配置中(假设共享库名为 'libhello.so')

cp libhello.so /usr/local/lib
 echo /usr/local/lib > /etc/ld.so.conf.d/local.conf
 /sbin/ldconfig

在php/ext目录下创建扩展头文件,取名为myfunctions.def
在该文件里填写c函数声明即可。每个函数一行。

string hello(int a)
 int hello_add(int a, int b)

使用ext_skel搭建扩展骨架

./ext_skel --extname=myfunctions --proto=myfunctions.def

打开config.m4 中的enable开关

PHP_ARG_ENABLE(myfunctions, whether to enable myfunctions support, 
 [ --enable-myfunctions        Include myfunctions support])

上面把扩展骨架建立好了,下面重新配置php (下面是我个人配置文件,读者需要结合自己情况修改)

./buildconf --force  //生成新配置脚本
 './configure' '--prefix=/usr/local/php' '--with-libdir=lib64' '--enable-fpm' '--with-fpm-user=php-fpm' '--with-fpm-group=www--enable-mysqlnd' '--with-mysql=mysqlnd' '--with-mysqli=mysqlnd' '--with-pdo-mysql=mysqlnd' '--enable-opcache' '--enable-pcntl' '--enable-mbstring' '--enable-soap' '--enable-zip' '--enable-calendar' '--enable-bcmath' '--enable-exif' '--enable-ftp' '--enable-intl' '--with-openssl' '--with-zlib' '--with-curl' '--with-gd' '--with-zlib-dir=/usr/lib' '--with-png-dir=/usr/lib' '--with-jpeg-dir=/usr/lib' '--with-gettext' '--with-mhash' '--with-ldap' '--disable-fileinfo' '--with-config-file-path=/usr/local/php/etc' '--with-apxs2=/usr/local/httpd/bin/apxs' '--enable-myfunctions' // 配置

 记住!一定在末尾加上 —enable-myfunctions 。这样子才会被编译进php中。
当扩展编译进去了之后,就可以开始修改扩展里的myfunctions.c文件,在里面可以添加php->c的转接函数,在转接函数里可以调用.so内的函数。
比如要添加一个hello_add的php函数,里面可以调用c函数add(int a, int b)
a. 添加函数声明

PHP_FE(hello_add, NULL)

b. 添加php函数

PHP_FUNCTION(hello_add){ ... }

注意,在该函数里,如果调用了.so文件里的接口函数,那么待会在make的时候,要指定所使用的.so共享库,该共享库必须完成第1步中添加到系统配置的操作。
如果调用了.so文件,那么要在php/Makefile中添加

Extra_LDFLAG = -lhello //对应前面的libhello.so
Extra_libs = -lhello
(make clean)

每次修改完上面的c文件,都要重新make

make
make install

重启apache服务器

httpd -k restart

在phpinfo里可以看到新扩展,可以直接在php调用新扩展内的函数。

PHP 相关文章推荐
php ajax 静态分页过程形式
Sep 02 PHP
使用PHPMyAdmin修复论坛数据库的图文方法
Jan 09 PHP
PHP跳转页面的几种实现方法详解
Jun 08 PHP
PHP mysql与mysqli事务使用说明 分享
Aug 17 PHP
Server.HTMLEncode让代码在页面里显示为源代码
Dec 08 PHP
Thinkphp将二维数组变为标签适用的一维数组方法总结
Oct 30 PHP
thinkPHP多域名情况下使用memcache方式共享session数据的实现方法
Jul 21 PHP
Laravel学习教程之View模块详解
Sep 18 PHP
PHP开发的文字水印,缩略图,图片水印实现类与用法示例
Apr 12 PHP
PHP+redis实现微博的推模型案例分析
Jul 10 PHP
thinkphp3.2框架中where条件查询用法总结
Aug 13 PHP
PHP安全之register_globals的on和off的区别
Jul 23 PHP
php实现无限级分类查询(递归、非递归)
Mar 10 #PHP
Zend Framework教程之Application和Bootstrap用法详解
Mar 10 #PHP
Zend Framework教程之配置文件application.ini解析
Mar 10 #PHP
PHP浮点数的一个常见问题
Mar 10 #PHP
简单谈谈php浮点数精确运算
Mar 10 #PHP
PHP实现仿百度文库,豆丁在线文档效果(word,excel,ppt转flash)
Mar 10 #PHP
Zend Framework教程之Loader以及PluginLoader用法详解
Mar 09 #PHP
You might like
删除无限级目录与文件代码共享
2006/07/12 PHP
深入解析php之apc
2013/05/15 PHP
php简单获取文件扩展名的方法
2015/03/24 PHP
php动态添加url查询参数的方法
2015/04/14 PHP
PHP扩展开发教程(总结)
2015/11/04 PHP
php把时间戳转换成多少时间之前函数的实例
2016/11/16 PHP
php 根据URL下载远程图片、压缩包、pdf等文件到本地
2019/07/26 PHP
childNodes.length与children.length的区别
2009/05/14 Javascript
JS实现标签页效果(配合css)
2013/04/03 Javascript
jquery 追加tr和删除tr示例代码
2013/09/12 Javascript
Jquery插件easyUi表单验证提交(示例代码)
2013/12/30 Javascript
谈谈基于iframe、FormData、FileReader三种无刷新上传文件的方法
2015/12/03 Javascript
jQuery实现日期联动效果实例
2016/07/26 Javascript
node.js中grunt和gulp的区别详解
2017/07/17 Javascript
JS图片延迟加载插件LazyImgv1.0用法分析【附demo源码下载】
2017/09/04 Javascript
日期时间范围选择插件:daterangepicker使用总结(必看篇)
2017/09/14 Javascript
微信小程序scroll-view组件实现滚动动画
2018/01/31 Javascript
手把手带你封装一个vue component第三方库
2019/02/14 Javascript
vue中的.$mount('#app')手动挂载操作
2020/09/02 Javascript
vue实践---vue不依赖外部资源实现简单多语操作
2020/09/21 Javascript
python实现闹钟定时播放音乐功能
2018/01/25 Python
对python中xlsx,csv以及json文件的相互转化方法详解
2018/12/25 Python
python 判断字符串中是否含有汉字或非汉字的实例
2019/07/15 Python
一文了解python 3 字符串格式化 F-string 用法
2020/03/04 Python
HTML5的语法变化介绍
2013/08/13 HTML / CSS
汤米巴哈马官方网站:Tommy Bahama
2017/05/13 全球购物
世界排名第一的万圣节服装店:Spirit Halloween
2018/10/16 全球购物
员工入职担保书范文
2014/04/01 职场文书
环保建议书600字
2014/05/14 职场文书
学校节能减排倡议书
2014/05/16 职场文书
环境工程专业自荐信范文
2014/06/24 职场文书
合作协议书格式
2014/08/19 职场文书
2016年度创先争优活动总结
2016/04/05 职场文书
浅谈Python中的函数(def)及参数传递操作
2021/05/25 Python
Python还能这么玩之只用30行代码从excel提取个人值班表
2021/06/05 Python
浅谈GO中的Channel以及死锁的造成
2022/03/18 Golang