欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

PHP的C扩展如何调用第三方库

程序员文章站 2022-06-05 18:29:14
...
由于本人是写C的所以对这个事情不是很了解,首先说明一下是程序在linux下,php的版本是5.3.13,我用C写的一个简单的加法运算的php扩展是可以使用的,我想问题就出在没有正确的链接进C的库
C库为两种类型:
1.是linux系统本身就自带的,但是需要在gcc编译可执行文件的时候用-l去链接,比如C的线程库 -lpthread

2.是第三方的,比如我现在有一个C的.so动态链接库libdecode.so,提供了一个C的API函数long SetCode(long l_input);

我改写的供php调用的函数是这么写的
PHP_FUNCTION(php_setcode){long arg_1 = 0;long re = 0;if(zend_parse_parameter(ZEND_NUM_ARGS() TSRMLS_CC, "l", &arg_1) == FAILURE){return;}re = SetCode(arg_1);}

config.m4里添加了

PHP_ADD_LIBRARY_WITH_PATH(decode, /home/wzb/lib, TEST_SHARED_LIBADD)
PHP_ADD_INCLUDE(/home/wzb/include)

执行命令
./congfigure --with-php-config=/usr/local/php/bin/php-config
make


并把生成的test.so和C的第三方库libdecode.so都复制到了/usr/local/php/lib/php/extension/no-debug-non-zts-20090626下
现在我在php.ini已经添加了如下的语句
extension=test.so
extension=libdecode.so

最后在php里无法成功调用php_setcode的函数

请教上述步骤我哪里需要补充才能实现对php_setcode的调用

回复讨论(解决方案)

你想实现c处理功能还是就是想让php调用自定义函数,若是后者为啥不做成php扩展呢
若是前者:http://blog.csdn.net/franzhong/article/details/7265429

你想实现c处理功能还是就是想让php调用自定义函数,若是后者为啥不做成php扩展呢
若是前者:http://blog.csdn.net/franzhong/article/details/7265429
是这样子的,libdecode.so不是我写的库,是由第三方提供的C库,我就是准备写一个PHP扩展来调用这个C库,编译都没有问题,就是差最后一步,知道如何把这个第三方库给链进来。我并没有libdecode.so这个库的源代码.c文件

这与是否是 php 扩展并无关系

你只需知道如何在 c 程序中连接 so 即可
这不是 php 的问题,请到 C/C++ 版面求解,那里高人很多

咱不懂, 网上找个教程折腾折腾吧, 从原理角度, php得包含头文件, 执行时得dl系列动态加载动态库内的接口, 你需要告诉php有哪些接口是你动态库暴漏出来的.

到你生成的自定义扩展的父目录下,应该是ext目录吧。看看其实扩展是怎么实现的,比如mysql

#清除
make clean

#添加模块ncdocxml
./configure --with-php-config=/usr/nc-home/php5/bin/php-config --enable-ncdocxml

#编译模块ncdocxml
make LDFLAGS=-lncdocxml

这与是否是 php 扩展并无关系

你只需知道如何在 c 程序中连接 so 即可
这不是 php 的问题,请到 C/C++ 版面求解,那里高人很多
在C里面链接动态库是在最后生成可执行程序时(相当于windows下的.exe)链接的,这时候的问题就是最后可执行程序是PHP而不是C,所以最后一步链接.so并非由C来完成

本帖最后由 xuzuning 于 2012-06-07 14:14:13 编辑

你说的那是静态加载,你只有 so 没有对应的 lib 文件和头文件。是不可能实现静态加载的
你需要的是动态加载,这当然是在c程序里完成的。比如 window 下的 BC 就有 LoadLibrary 函数来加载指定的 dll,当然没有头文件也还是很痛苦的

另外我们在 vb、vfp 中都一直通过动态加载操作系统的动态链接库来完成脚本语言不可能完成的工作

帮你找了这篇博文供参考 http://blog.csdn.net/offbye/article/details/6832536

你说的那是静态加载,你只有 so 没有对应的 lib 文件和头文件。是不可能实现静态加载的
你需要的是动态加载,这当然是在c程序里完成的。比如 window 下的 BC 就有 LoadLibrary 函数来加载指定的 dll,当然没有头文件也还是很痛苦的

另外我们在 vb、vfp 中都一直通过动态加载操作系统的动态链接库来完成脚本语言不可能完成的工作
当然头文件是有的,不然就不会编译成功了,关于这个动态加载的问题,其实生成可执行程序时有-ldl这个编译选项,最终会涉及到需要在php去链接这个libdl.so这个linux系统自带的动态库,就是把我上述的问题从libdecode.so换成了libdl.so
还是非常感谢你的热心帮助

感谢各位,问题已经解决了,问题应该还是出在config.m4这里。解决方法如下:
vi config.m4
再config.m4中添加
PHP_ADD_LIBRARY_WITH_PATH(decode, /home/wzb/lib, TEST_SHARED_LIBADD)
PHP_ADD_INCLUDE(/home/wzb/include)
PHP_SUBST(TEST_SHARED_LIBADD)

然后依次执行命令
phpize
./configure --enable-test --with-php-config=/usr/local/php/bin/php-config
make

最后在modules得到的PHP的扩展库test.so,可以实现对libdecode.so的C的API函数的调用

你好,请问下你那个除了这个地方做了处理之外还在哪个地方做了处理呢,我碰到类似的问题,目前没有办法处理啊

感谢各位,问题已经解决了,问题应该还是出在config.m4这里。解决方法如下:
vi config.m4
再config.m4中添加
PHP_ADD_LIBRARY_WITH_PATH(decode, /home/wzb/lib, TEST_SHARED_LIBADD)
PHP_ADD_INCLUDE(/home/wzb/include)
PHP_SUBST(TEST_SHARED_LIBADD)

然后依次执行命令
phpize
./configure --enable-test --with-php-config=/usr/local/php/bin/php-config
make

最后在modules得到的PHP的扩展库test.so,可以实现对libdecode.so的C的API函数的调用