您的位置:首页 > 编程语言 > C语言/C++

在 windows 下 用C++ 开发 PHP 扩展

2010-11-05 16:45 211 查看
我翻遍了Google, 也没用找到一篇真正能运行的C++ 下面 开发 PHP 扩展的文章。于是,我又翻遍了pecl,看看有没有例子。
发现还是没有。唯一能看到的几个是:Linux 下面 开发 C++ 扩展的文章,一试,发现时 php 5.0 beta 时候的文章了,都已经
过时了。无奈只能自己摸索。
后来,在没有思路的时候,我觉得先编译PHP 开发包。结果,费了九牛二虎之力终于把 PHP 5.2 和 5.3 都在 visual stdio 下面编译
成功了。我编译了一个release 版本, 一个 debug 版本。release 版本 其实在 PHP 安装目录的 dev 下面有,如果不要debug 版本的,
可以直接用内置release,不需要编译 PHP 的开发包了。
编译了PHP 之后,开始有些明白PHP 扩展 是怎么回事了。其实就是一个动态链接库。
我通过 内置的 ext_skel_win32.php 生成一个扩展工程。当然,要做点改动,这个工程比较旧了,是对vc 6.0 的。
在 配置属性 ==》 c/c++ ==> 预处理定义 加一个 : _USE_32BIT_TIME_T 。这是 因为 vs 2005 用的是 64位的时间,
而zend 引擎默认是 32 位。
在很多手册里面,都说要加 extern "c" {} 在头文件里面,实际上,根本就没有必要了,如果你只是些 5.2 以上的扩展的话。已经内部加好了。
这样,就能编译扩展了。记住,是release 版本的,如果要编译debug 版本的,那么就重新编译吧PHP吧。
下面我说说 如何转换 C++ 的类,到 PHP。
比如 我有个 Dog 类,有个方法叫做 bark() 有个属性叫做 name(主意写法有很多种,我只是介绍一种)


zend_object_handlers dog_object_handlers;
zend_class_entry *dog_ce;

struct dog_object {
zend_object std; // PHP 标准类
Dog *dog; // dog 类
};

// 释放内存
void dog_free_storage(void *object TSRMLS_DC)
{
dog_object *obj = (dog_object *)object;

delete obj->dog;

zend_hash_destroy(obj->std.properties);
FREE_HASHTABLE(obj->std.properties);

efree(obj);
}

// 创建内置PHP 类,其实类就是一个 zend hash
zend_object_value dog_create_handler(zend_class_entry *type TSRMLS_DC)
{
zval *tmp;
zend_object_value retval;

dog_object *obj = (dog_object *)emalloc(sizeof(dog_object));
memset(obj, 0, sizeof(dog_object));
obj->std.ce = type;

ALLOC_HASHTABLE(obj->std.properties);
zend_hash_init(obj->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
zend_hash_copy(obj->std.properties, &type->default_properties,
(copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *));

retval.handle = zend_objects_store_put(obj, NULL,
dog_free_storage, NULL TSRMLS_CC);
retval.handlers = &dog_object_handlers;

return retval;
}

PHP_METHOD(Dog, __construct)
{
string name;
Dog *dog = NULL;
zval *object = getThis();

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name) == FAILURE) {
RETURN_NULL();
}

dog = new Dog(name);
dog_object *obj = (dog_object *)zend_object_store_get_object(object TSRMLS_CC);
obj->dog = dog;
}

PHP_METHOD(Dog, bark)
{
Dog *dog;
dog_object *obj = (dog_object *)zend_object_store_get_object(
getThis() TSRMLS_CC);
dog = obj->dog;
if (dog != NULL) {
dog->bark();
}
}

function_entry dog_methods[] = {
PHP_ME(Dog, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
PHP_ME(Dog, bake, NULL, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};

PHP_MINIT_FUNCTION(cplusplusdog)
{
zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "Dog", dog_methods);
dog_ce = zend_register_internal_class(&ce TSRMLS_CC);
dog_ce->create_object = dog_create_handler;
memcpy(&dog_object_handlers,
zend_get_std_object_handlers(), sizeof(zend_object_handlers));
dog_object_handlers.clone_obj = NULL;
return SUCCESS;
}

好了,不罗嗦了,可以说,zend 2.2 已经非常的支持 C++ 写扩展了。c++的开发效率对我这样的菜鸟来说要比c快
很多。



本文转载自: http://www.cnblogs.com/niniwzw/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: