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

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

  我翻遍了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快
很多。
posted @ 2009-08-15 11:47 暮夏 阅读( ...) 评论( ...) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值