扩展名php:php的c扩展
来源: 发布时间:星期六, 2009年9月12日 浏览:21次 评论:0
在php中最核心 ![](/icons/37391de.gif) ![](/icons/37391yi.gif) 个数据结构就是这个: typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { char *val; len; } str; HashTable *ht; /* hash table value */ zend_object_value obj; } zvalue_value; struct _zval_struct { /* Variable information */ zvalue_value value; /* value */ zend_u refcount; zend_uchar type; /* active type */ zend_uchar is_ref; }; 这个数据结构也就是php中 ![](/icons/37391de.gif) 每个数据类型在下层c语言中 ![](/icons/37391de.gif) 表示 ![](/icons/37391dou2.gif) 可以看到_zval_struct 结构体第 ![](/icons/37391yi.gif) 个字段是 ![](/icons/37391yi.gif) 个联合体 ![](/icons/37391dou.gif) 他来存储实际 ![](/icons/37391de.gif) 值 ![](/icons/37391dou.gif) 这些值可以为long ![](/icons/37391dou.gif) double ![](/icons/37391dou.gif) ![](/icons/37391zifu.gif) 串 ![](/icons/37391dou.gif) hashtable(也就是php中 ![](/icons/37391de.gif) ![](/icons/37391shuzu.gif) )和对象 ![](/icons/37391dou2.gif) 而第2个参数是个引用计数 ![](/icons/37391dou.gif) 第 3个参数是当前 ![](/icons/37391de.gif) 类型 也就是说php中 ![](/icons/37391de.gif) 每个类型实际都是 ![](/icons/37391yi.gif) 个 struct _zval_struct类型 1 首先进入php ![](/icons/37391de.gif) 源码目录下 ![](/icons/37391de.gif) ext文件夹 ![](/icons/37391dou.gif) 然后运行下面 ![](/icons/37391de.gif) 命令,这样将会生成 ![](/icons/37391yi.gif) 个my_module ![](/icons/37391de.gif) 文件夹 ![](/icons/37391dou2.gif) : ./ext_skel --extname=my_module 2 然后在my_module.h里面声明你 ![](/icons/37391de.gif) php ![](/icons/37391hanshu.gif) 名: PHP_FUNCTION(my_function); 2 在my_module.c文件 ![](/icons/37391de.gif) my_module_functions(这里 ![](/icons/37391de.gif) module就是你所创建 ![](/icons/37391de.gif) 扩展模块名字)加入你所要写 ![](/icons/37391de.gif) php思路方法名: PHP_FE(my_function, NULL) 3 接下来就实现PHP_FUNCTION(my_function) 首先 参数 ![](/icons/37391de.gif) 解析 ![](/icons/37391dou.gif) 当传递进来 ![](/icons/37391de.gif) php ![](/icons/37391de.gif) 类型和c ![](/icons/37391de.gif) 类型的间 ![](/icons/37391de.gif) 转换:
这里要用到 ![](/icons/37391de.gif) ![](/icons/37391hanshu.gif) 是: zend_parse_parameters( num_args TSRMLS_DC, char *type_spec, ...);
其中 ![](/icons/37391de.gif) php类型和c类型 ![](/icons/37391de.gif) 对应如下: 引用 l - long d - double s - ![](/icons/37391string.gif) (with possible null ![](/icons/37391byte.gif) s) and its length b - boolean r - resource, stored in zval* a - ![](/icons/37391<img src=) .gif' />, stored in zval* o - object (of any ![](/icons/37391class.gif) ), stored in zval* O - object (of ![](/icons/37391class.gif) spec ![](/icons/37391if.gif) ied by ![](/icons/37391class.gif) entry), stored in zval* z - the actual zval* 这边就看到了 ![](/icons/37391dou.gif) 这里 ![](/icons/37391de.gif) zval也就是 ![](/icons/37391yi.gif) 开始介绍 ![](/icons/37391de.gif) 那个php ![](/icons/37391de.gif) 类型结构体 这边还可以使用 3个符号: | - 这个也就是或者 ![](/icons/37391de.gif) 意思 / -将会提供当前参数 ![](/icons/37391de.gif) ![](/icons/37391yi.gif) 个副本 ! - 这个符号他必须进跟在a, o, O, r, z ![](/icons/37391de.gif) 后面 ![](/icons/37391dou.gif) 也就是说当传递进来 ![](/icons/37391de.gif) 参数为NULL ![](/icons/37391de.gif) 时候 ![](/icons/37391dou.gif) 我们pass ![](/icons/37391de.gif) 那个指针也会被NULL 例子: /* 得到 个long![](/icons/37391dou.gif) 和 个zval */ long l; char *s;
s_len; zval *param;
(zend_parse_parameters(ZEND_NUM_ARGS TSRMLS_CC, "lsz", &l, &s, &s_len, ¶m) FAILURE) { ; } /*传递进来 为 个对象或者 个double */ zval *obj; double d = 0.5;
(zend_parse_parameters(ZEND_NUM_ARGS TSRMLS_CC, "O|d", &obj, my_ce, &d) FAILURE) { ; } /* 传递进来 参数为NULL或者 个对象和 个 */ zval *obj; zval *arr;
(zend_parse_parameters(ZEND_NUM_ARGS TSRMLS_CC, "O!a", &obj, &arr) FAILURE) { ; } /* 得到 个 */ zval *arr;
(zend_parse_parameters(ZEND_NUM_ARGS TSRMLS_CC, "a/", &arr) FAILURE) { ; } /*得到前 3个参数 */ zval *z; zend_bool b; zval *r;
(zend_parse_parameters(3, "zbr!", &z, &b, &r) FAILURE) { ; }
当我们传递进来 ![](/icons/37391de.gif) 为 ![](/icons/37391yi.gif) 个 ![](/icons/37391shuzu.gif) ![](/icons/37391de.gif) 时候我们该如何遍历这个 ![](/icons/37391shuzu.gif) 呢 ![](/icons/37391dou.gif) 看下面 ![](/icons/37391de.gif) 代码: zval *param; HashPosition pos; zval **data_value; (zend_parse_parameters(ZEND_NUM_ARGS TSRMLS_CC, "a", &(param)) FAILURE) { RETURN_FALSE; } //遍历 . for (zend_hash_ ernal_po er_re _ex(Z_ARRVAL_P(param), &pos); zend_hash_get_current_data_ex(Z_ARRVAL_P(param), (void **)&data_value, &pos) SUCCESS; zend_hash_move_forward_ex(Z_ARRVAL_P(param), &pos)) { //现在 里面 值就存储在data_value这个指针里面 我们可以通过对他解引用来提取值 比如假设有个元素是long![](/icons/37391de.gif) 那么我们就可以这样来取(就是根据 开头介绍 那个数据结构来取): long temp=(*data_value)->value.lval; } 接下来是返回值 ![](/icons/37391de.gif) 问题,这里定义了好几个宏: RETURN_RESOURCE( r) RETURN_BOOL( b) RETURN_NULL( ) RETURN_LONG( l) RETURN_DOUBLE(double d) RETURN_STRING(char *s, dup) RETURN_STRINGL(char *s, l, dup) RETURN_EMPTY_STRING( ) RETURN_FALSE RETURN_TRUE 比如我要返回个 ![](/icons/37391zifu.gif) 串 ![](/icons/37391dou.gif) 可以这么写: RETURN_STRING("banana", 1); 这里讲下返回 ![](/icons/37391yi.gif) 个 ![](/icons/37391shuzu.gif) ![](/icons/37391de.gif) 问题,下面 ![](/icons/37391de.gif) 代码是返回 ![](/icons/37391yi.gif) 个嵌套 ![](/icons/37391shuzu.gif) : zval *param:
.gif' />_init(param); // _value是 个全局 变量(我是这么理解 )
.gif' />_init( _value); add_index_ (param, 0, "sad",1); add_index_zval( _value,0, param); PS:更详细 ![](/icons/37391de.gif) 还是要看ext目录下面 ![](/icons/37391de.gif) 那些扩展例子
相关文章
读者评论
发表评论
|
|