PHP扩展编写点滴 技巧收集

红色部分是我的注释。
更多信息参看:

1.常用的通用功能已经封装好了,在如zen_API.h 头文件中,不用费力查看内部细节,浪费时间。(参考:Extending and Embedding PHP 的附录A)
2.在terminal中运行测试程序,可以看到扩展的内部错误输出,这一点对于解决内存泄漏问题尤其重要。(编译一个debug 的 lib)
3.开发过程中修改Makefile中的“CFLAGS = -g -O2”,去掉优化选项,增加-Wall和-pedantic,便于调试和显示编译警告;
4.某zval*,但其strval非拷贝的,不可用zval_ptr_dtor(zval**),要用efree(void*)。
5.terminal中的$_SERVER['PWD']有值,但是无法通过zend_getenv()取得,原因应该是该值无意义或不可靠。
6.调用“导出函数”,可利用INTERNAL_FUNCTION_PARAM_PASSTHRU传参;声明的非导出函数可通过INTERNAL_FUNCTION_PARAM使用“导出函数”的参数。
7.注意:RETURN_TYPE用在选择分之和循环等处时,最好置于花括号中,
或者不用分号,因为:#define RETURN_BOOL(b) { RETVAL_BOOL(b); return; }。
8.如果函数的参数是引用的,且非标量,要先析构,以防内存泄露。
9.抛出异常前最好判断EG(exception)中是否已经存在异常,否则会造成内存泄露。
10.当Web服务器API是ISAPI (IIS)的时候,zend_getenv函数是不起作用的。
11.向zend_stack_push()传入数据指针,实际存储(copy)的是该指针指向的数据,换句话说,传入的应该是要存储的数据的指针。
ZEND_API int zend_stack_push(zend_stack *stack, void *element, int size);
ZEND_API int zend_stack_top(zend_stack *stack, void **element);
其中,size == sizeof(*element);
类似地,zend_hash也是如此,比较zend_hash_update和zend_hash_find。
12.使用add_assoc_zval(HashTable*, const char*, zval*)存储的是zval*,而非zval,因此,
存储用户传入的参数时候,要先拷贝一份新的zval,否则会发生不可预料的事情。
13.zval_dtor(zval*)释放变量及其内部的引用内存,zval_ptr_dtor(zval**)先检查refcount
再决定是否调用zval_dtor(zval*),zval_copy_dtor(zval*)仅执行深层的拷贝,即只拷贝
起内部引用的内存,而不拷贝zval;

14.如使用VC编译win的动态链接库,而且代码中调用了zend函数,如zend_getenv,在zend.h中定义为:

extern "C" {
extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
}
需要引入该函数,如要使用ZEND_API,需要事先取消LIBZEND_EXPORTS(包括VC“设置”中的预处理定义),或者使用ZEND_DLIMPORT,
ZEND_DLIMPORT char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
下面取自:zend_config.w32.h


代码如下:

#ifdef LIBZEND_EXPORTS
# define ZEND_API __declspec(dllexport)
#else
# define ZEND_API __declspec(dllimport)
#endif
#define ZEND_DLEXPORT __declspec(dllexport)
#define ZEND_DLIMPORT __declspec(dllimport)

executor_globals_id也需要作如下声明:
ZEND_DLIMPORT int executor_globals_id;
(这个比较有用,如果你要手工编译某些扩展的时候,比如我在编译sqlite3这个扩展的时候,就遇到这个问题。)

(0)

相关推荐

  • PHP扩展编写点滴 技巧收集

    红色部分是我的注释. 更多信息参看: 1.常用的通用功能已经封装好了,在如zen_API.h 头文件中,不用费力查看内部细节,浪费时间.(参考:Extending and Embedding PHP 的附录A) 2.在terminal中运行测试程序,可以看到扩展的内部错误输出,这一点对于解决内存泄漏问题尤其重要.(编译一个debug 的 lib) 3.开发过程中修改Makefile中的"CFLAGS = -g -O2",去掉优化选项,增加-Wall和-pedantic,便于调试和显示编

  • Spring扩展BeanFactoryPostProcessor使用技巧详解

    目录 1.Spring 扩展点 BeanFactoryPostProcessor 使用技巧 1.1.BeanDefinitionRegistryPostProcessor 1.1.1.ScannedGenericBeanDefinition 1.1.2.AnnotatedGenericBeanDefinition 1.1.3.RootBeanDefinition 1.2.环境变量 Environment 1.Spring 扩展点 BeanFactoryPostProcessor 使用技巧 方法

  • 浅谈C语言编程中程序的一些基本的编写优化技巧

    大概所有学习C语言的初学者,都被前辈说过,C语言是世界上接近最速的编程语言,当然这并不是吹牛,也并不是贬低其他语言,诚然非C语言能写出高速度的代码,但是C语言更容易写出高速的程序(高速不代表高效),然而再好的工具,在外行人手中也只能是黯淡没落. 对于现代编译器,现代CPU而言,我们要尽量迎合CPU的设计(比如架构和处理指令的方式等),虽然编译器是为程序员服务,并且在尽它最大的能力来优化程序员写出的代码,但是毕竟它还没有脱离电子的范畴,如果我们的代码不能让编译器理解,编译器无法帮我们优化代码,那么

  • 60个很实用的jQuery代码开发技巧收集

    由于内容比较多建议用CTRL+F搜索 偶然在网上看到这些不错的jQuery代码开发技巧.原文收集了30个,另外查找的时候发现了还有20个.加上另外十个实用的jQuery代码片段,共60个代码技巧,收集在一起分享给大家. 1. 创建一个嵌套的过滤器 .filter(":not(:has(.selected))") //去掉所有不包含class为.selected的元素 2. 重用你的元素查询 var allItems = $("div.item"); var keep

  • Linux Shell的一些使用小技巧收集

    检查远程端口是否对bash开放: 复制代码 代码如下: echo >/dev/tcp/8.8.8.8/53 && echo "open" 让进程转入后台: 复制代码 代码如下: Ctrl + z 将进程转到前台: 复制代码 代码如下: fg 产生随机的十六进制数,其中n是字符数: 复制代码 代码如下: openssl rand -hex n 在当前shell里执行一个文件里的命令: 复制代码 代码如下: source /home/user/file.name 截取

  • 常用的jQuery前端技巧收集

    调试时巧用console.log(),这比用alert()方便多了. jquery易错点:元素拼接的时候,元素还未添加到DOM,就用该预添加元素操作. ajax动态获取的数据,还没有装载html元素,下面就开始用预拼凑的元素操作. 复制代码 代码如下: <li onclick="Show('10')">     <a href='javascript:void()'>提交</a> </li> 这样写,点击"提交"的时候

  • Jquery常用技巧收集整理篇

    比如有禁止右键点击.隐藏搜索文本框文字.在新窗口中打开链接.检测浏览器.预加载图片等等.具体如下: 禁止右键点击 复制代码 代码如下: $(document).ready(function(){ $(document).bind("contextmenu",function(e){ return false; }); }); 隐藏搜索文本框文字 复制代码 代码如下: $(document).ready(function() { $("input.text1").va

  • js技巧收集(200多个) 超强推荐第1/2页

    1.文本框焦点问题 onBlur:当失去输入焦点后产生该事件 onFocus:当输入获得焦点后,产生该文件 Onchange:当文字值改变时,产生该事件 Onselect:当文字加亮后,产生该文件 <input type="text" value="郭强" onfocus="if(value=='郭强') {value=''}" onblur="if  (value=='') {value='郭强'}">点击时文字

  • flex 优化技巧 收集[提升性能]

    1.当创建一个数组的时候避免用new操作符,用 var a:Array = [];而不用var a:Array = new Array(); 2.快速的复制一个数组: var copy : Array = sourceArray.concat (); 3.设置一个数组的值是非常忙的: employees.push ( employee ); employees[2] = employee; 4.从一个数组中取得值的速度是设置一个数组值的两倍快: var employee : Employee =

  • 综合门诊|技巧收集|DIY综合实用技巧

    轻松逃过IE7验证在安装IE7时,到验证步骤时请不要点验证,进入系统盘:\Documents and Settings\All Users\Application Data\Windows Genuine Advantage\data下将data.dat文件移到桌面,再点验证即可轻松逃过. 教大家如何DIY自己电脑右下角时间点开始----设置----控制面板---区域和语言(98是区域设置)选项-----自定义----时间----时间格式 (T)里的H:mm:ss前加两个tt ttH:mm:ss

随机推荐