zoukankan      html  css  js  c++  java
  • 在 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, 
    0sizeof(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快
    很多。
  • 相关阅读:
    爬虫之四种数据解析方式
    爬虫之爬虫概述
    <转载>面试官,不要再问我三次握手和四次挥手
    <转载>面试官: 讲讲MySql表设计需要注意什么?
    HTTP协议的特点
    Django之FORM
    Django之ajax
    csrf的中间件
    Django之中间件
    删除/tmp目录下txt文件
  • 原文地址:https://www.cnblogs.com/niniwzw/p/1546715.html
Copyright © 2011-2022 走看看