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快
    很多。
  • 相关阅读:
    win10 UWP button
    内网分享资源
    内网分享资源
    CF724F Uniformly Branched Trees
    win10 UWP FlipView
    win10 UWP FlipView
    win10 UWP FlipView
    搭建阿里云 centos mysql tomcat jdk
    搭建阿里云 centos mysql tomcat jdk
    win10 UWP 申请微软开发者
  • 原文地址:https://www.cnblogs.com/niniwzw/p/1546715.html
Copyright © 2011-2022 走看看