需求
在开PHPOpenCV扩展,在写php的createTrackbar
方法的时候,需要实现用户传入的一个闭包,而闭包在C++createTrackbar
滑动事件时候调用
结果如下:
createTrackbar('trackBarName',"winName",100,200,function($num){
//$num为滑动条选中值
});
实现
首先要获取用户传入闭包
char *trackbarname, *winname;
long value, count, trackbarname_len,winname_len;
zval retval;
zend_fcall_info fci;
zend_fcall_info_cache fci_cache;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "ssll|f",
&trackbarname, &trackbarname_len,
&winname,&winname_len,
&value,&count,
&fci, &fci_cache) == FAILURE) {
return;
}
用户传入的闭包保存在fci
和fci_cache
变量当中
c++ 版的createTrackbar
最后可以值可以传入自己的值,从而在回调当中带入
所以我们要新建一个struct把fci和fci_cache包在一起
struct opencv_fcall_info_cb{
zend_fcall_info *fci;
zend_fcall_info_cache *fci_cache;
};
结构体定义好了,我们需要定义他的生成方法,因为C++直接用”=”复制,fci
和fci_cache
变量是方法中的局部变量,如果离开了方法就会释放,
我们要为传入的值创建内存,并且拷贝必要的信息(包括一些指针的值)
opencv_fcall_info_cb * opencv_fcall_info_cb_create(zend_fcall_info *fci_ptr, zend_fcall_info_cache *fci_cache_ptr) {
opencv_fcall_info_cb *cb = new opencv_fcall_info_cb;
cb->fci = new zend_fcall_info;
cb->fci_cache = new zend_fcall_info_cache;
memcpy(cb->fci, fci_ptr, sizeof(zend_fcall_info));
memcpy(cb->fci_cache, fci_cache_ptr, sizeof(zend_fcall_info_cache));
Z_TRY_ADDREF(cb->fci->function_name);
cb->fci->param_count = 0;
cb->fci->no_separation = 1;
cb->fci->retval = NULL;
return cb;
}
最后在方法中调用
opencv_fcall_info_cb *cb = opencv_fcall_info_cb_create(&fci, &fci_cache);
createTrackbar(trackbarname, winname, trackbar_value_ptr, (int)count,opencv_create_trackbar_callback,cb);
最后是opencv_create_trackbar_callback
方法
void opencv_create_trackbar_callback(int pos, void* userdata){
opencv_fcall_info_cb *fci_s=(opencv_fcall_info_cb*)userdata;
zval retval;
zval args[1];
ZVAL_LONG(&args[0], (long)pos);//将滑动条滑动的值传入到闭包参数中
fci_s->fci->param_count = 1;
fci_s->fci->params = args;
fci_s->fci->retval = &retval;
zend_call_function(fci_s->fci, fci_s->fci_cache);
zval_ptr_dtor(&args[0]);
}
—End—
迭代
- 2017年07月28日 10:41 初稿