配置如下:
PHP_ARG_WITH(sysfile, for sysfile support,
[ --with-sysfile Include sysfile support])
if test "$PHP_SYSFILE" == "yes"; then
PHP_REQUIRE_CXX()
PHP_ADD_LIBRARY(stdc++)
PHP_NEW_EXTENSION(sysfile, sysfile.cpp c_sysfile/check.cpp c_sysfile/constraint.cpp c_sysfile/create.cpp c_sysfile/define.cpp c_sysfile/getdata.cpp c_sysfile/load.cpp c_sysfile/save.cpp c_sysfile/setdata.cpp c_sysfile/utility.cpp, $ext_shared)
fi
./configure --disable-all --with-sysfile=shared --with-apxs2=/usr/local/apache2/bin/apxs
make
顺利得到了一个sysfile.so,但是在测试的时候报错,说这是一个invalid PHP library.
我用的是PHP-4.4.4,这可能是什么原因呢?
谢谢!
goodtaste 回复于:2006-12-19 17:16:03
用ext_skel创建一个扩展的框架,比如myext
然后把myext.c改成myext.cpp,并且把对php.h等的#include用extern "C"修饰起来。
然后我就没有再增加任何C/C++代码了。
修改config.m4如下:
PHP_ARG_WITH(myext, for sysfile support,
[ --with-myext Include myext support])
if test "$PHP_MYEXT" == "yes"; then
PHP_REQUIRE_CXX()
PHP_ADD_LIBRARY(stdc++)
PHP_NEW_EXTENSION(myext, myext.cpp, $ext_shared)
fi
./configure --disable-all --with-myext=shared
make
得到的myext.so 用./sapi/cli/php ext/myext/myext.php 测试显示正确。
但是把myext.so复制到php的安装目录里并且在php.ini里用
extension=myext.so装载,就会出错,从Apache的日志里看到如下错误信息:
PHP Warning: Unknow(): Unable to load dynamic library '/usr/local/php/exts/myext.so' - /usr/local/php/exts/myext.so: undefined symbol: _Znaj in Unknown on line 0
_Znaj是C++标准库里的东西吧?我明明在config.m4里申明了
PHP_ADD_LIBRARY(stdc++)了呀。这是什么原因呢?
是不是用C++作PHP扩展的特别少?我们的项目应该要使用模版库,不得不
使用C++.
如果我使用C来做这个myext扩展,就一切正常。
谢谢~
[
本帖最后由 goodtaste 于 2006-12-19 17:17 编辑 ]
goodtaste 回复于:2006-12-19 17:36:42
myext的问题只要修改config.m4成:
PHP_ARG_WITH(myext, for sysfile support,
[ --with-myext Include myext support])
if test "$PHP_MYEXT" == "yes"; then
PHP_REQUIRE_CXX()
PHP_SUBST(MYEXT_SHARED_LIBADD)
PHP_ADD_LIBRARY(stdc++,"",MYEXT_SHARED_LIBADD)
PHP_NEW_EXTENSION(myext, myext.cpp, $ext_shared)
fi
就可以了。
但是我的实际工程sysfile在装载的时候还是报错:
Warning: dl(): Invalid library (maybe not a PHP library) 'sysfile.so'
帮帮我吧.
goodtaste 回复于:2006-12-19 18:19:37
我的ZEND_GET_MODULE前后忘记加extern "C"了,通过nm看导出函数名发现的.
呵呵,谢谢大家.
crazysoul 回复于:2006-12-19 22:02:47
楼主品格好啊
七夜 回复于:2006-12-22 14:45:16
编译的时候也要注意也要加相关的东西,不然编译出来的.so调用时,还会出现问题
goodtaste 回复于:2007-01-31 09:41:11
免得以后忘记了,也给其他一些帮助。
原文在
[url=http://jason.rocklv.net/techdoc/PHPExt.html]http://jason.rocklv.net/techdoc/PHPExt.html
在Linux上创建PHP4的C++扩展
Jason
1. 必须的工具
2. 主要步骤
2.1. 创建
2.2. 编译
2.3. 调试
3. 总结
1. 必须的工具
如下工具是必须的:
1.
gcc. 我使用的是3.4.3
2.
autoconf. 我使用的是 2.13-5. 奇怪的是2.59是不能用的,如果你的系统里安装的是这个版本,要先卸载,然后安装2.13
3.
PHP4的源代码。我使用的是PHP-4.4.4。在PHP的网站上可以下载到
2. 主要步骤
创建PHP的扩展很麻烦。熟悉其它脚本语言的人会觉得开发PHP的扩展真是罗嗦到了极点。不过给脚本写扩展的原理都是一样的:
导出一个特定名字的函数,然后通过这个函数返回关于这个扩展的全部信息,其中重要的有:
1.
名字,描述,版本信息
2.
模块所提供的功能,这个一般都是一个函数名和函数指针成对的数组
3.
通过一些函数实现脚本和扩展之间的数据交换.这方面各个语言都不相同,TCL是直接传递字符串,Python提供了PyArg_ParseTuple,Py_BuildValue等函数,Lua则通过一个堆栈来交换数据.
PHP提供了一系列的工具和宏来封装这个过程,可惜的是在我看来这反而让它更加复杂。
2.1. 创建
1.
将PHP-4 的源代码解压缩。下文将这个目录称为PHPSRC.
2.
进入PHPSRC/ext目录,执行./ext_skel 扩展名。假设我们的扩展名字叫testext,那就是输入./ext_skel testext. 这个程序将会为你在ext目录下创建如下内容:
1.
testext目录
2.
在testext目录下又包括:
1.
testext.c - 这是扩展模块的源文件
2.
php_testext.h - 头文件
3.
config.m4 - 用于autoconf的配置文件,autoconf会通过这个文件的内容决定应该如何编译链接这个模块。
4.
testext.php - 自动产生的测试脚本
5.
tests 目录 - 忽略
3.
然后我们必须简单的理解一下config.m4这个文件。
m4 is a macro processor, in the sense that it copies its input to the output, expanding macros as it goes. Macros are either builtin or user-defined, and can take any number of arguments. Besides just doing macro expansion, m4 has builtin functions for including named files, running shell commands, doing integer arithmetic, manipulating text in various ways, performing recursion, etc.... m4 can be used either as a front-end to a compiler, or as a macro processor in its own right.
The m4 macro processor