C库回调PHP中的函数例子的单参数,多参数如何实现的问题

时间:2022-10-13 17:37:27
本来这个问题在PHP发过,不过我发现绝大部分PHPer对PHP以外的语言,异构能力不太好。所以转到C论坛来了。



PHP的扩展回调PHP中的函数我找到了一个例子:
http://lostphp.com/blog/851.html


这个例子里被回调的PHP函数是单个参数的:
function get_site_url ($prefix) {
    return $prefix."www.lostphp.com\n";
}

call_function(null, "get_site_url", "site url:");


但是我的被回调的PHP函数是多个参数的:

function myfunction($height,$width,$name,$weigh) {

      echo("my height is $height\n");
      ......
     echo("my weigh is $weigh\n");
}


下面是例子的源码,我应该怎么修改呀?

这里看格式不舒服的话可以到原网页去看:http://lostphp.com/blog/851.html

php代码:

<?php
class demo {
    public function get_site_name ($prefix) {
        return $prefix."lostphp\n";
    }
}
function get_site_url ($prefix) {
    return $prefix."www.lostphp.com\n";
}
 
function call_function ($obj, $fun, $param) {
    if ($obj == null) {
        $result = $fun($param);
    } else {
        $result = $obj->$fun($param);
    }
    return $result;
}
$demo = new demo();
echo call_function($demo, "get_site_name", "site name:");
echo call_function(null, "get_site_url", "site url:");
?>


扩展中call_function的源码:

PHP_FUNCTION(call_function)
{
    zval            *obj = NULL;
    zval             *fun = NULL;
    zval             *param = NULL;
    zval             retval;
    zval             args[1];
 
#ifndef FAST_ZPP
    /* Get function parameters and do error-checking. */
    if (zend_parse_parameters(ZEND_NUM_ARGS(), "zzz", &obj, &fun, &param) == FAILURE) {
        return;
    }
#else
    ZEND_PARSE_PARAMETERS_START(3, 3)
        Z_PARAM_ZVAL(obj)
        Z_PARAM_ZVAL(fun)
        Z_PARAM_ZVAL(param)
    ZEND_PARSE_PARAMETERS_END();
#endif
 
    args[0] = *param;
    if (obj == NULL || Z_TYPE_P(obj) == IS_NULL) {
        call_user_function_ex(EG(function_table), NULL, fun, &retval, 1, args, 0, NULL);
    } else {
        call_user_function_ex(EG(function_table), obj, fun, &retval, 1, args, 0, NULL);
    }
    RETURN_ZVAL(&retval, 0, 1);
}

这里还有一个例子:

http://blog.csdn.net/xing_____/article/details/78481547

这里还有一个例子:

https://segmentfault.com/a/1190000007648157

都是单个参数的,感觉他们都只是研究性质,都是研究一个简单的 写个文章了事。真实场景下但参数很少的

2 个解决方案

#1


[发现了一些线索,希望有人能比我早研究出来:

http://blog.csdn.net/zhyl8157121/article/details/53032997




应该是第二个参数这里控制后面的参数个数和参数类型:"ss","s|s" 



参数  对应C里的数据类型

b   zend_bool

l   long

d   double

s   char*, int
前者接收指针,后者接收长度

r   zval*

a   zval*

o   zval*

O   zval*, zend_class_entry*

z   zval*

Z   zval**

http://blog.csdn.net/leonpengweicn/article/details/12946993?%3E, 补充资料:https://my.oschina.net/jackin/blog/172926
ZEND_API int call_user_function_ex(
    HashTable *function_table,
    zval **object_pp,
    zval *function_name,
    zval **retval_ptr_ptr,
    zend_uint param_count,
    zval **params[],
    int no_seperation,
    HashTable *symbol_table TSRMLS_DC);
params is an array of pointers to zval pointers. Note: this is _not_ a PHP/zval array, it is a C array. Example:

zval *foo; zval *bar; zval **params[2]; params[0] = &foo; params[1] = bar;]

#1


[发现了一些线索,希望有人能比我早研究出来:

http://blog.csdn.net/zhyl8157121/article/details/53032997




应该是第二个参数这里控制后面的参数个数和参数类型:"ss","s|s" 



参数  对应C里的数据类型

b   zend_bool

l   long

d   double

s   char*, int
前者接收指针,后者接收长度

r   zval*

a   zval*

o   zval*

O   zval*, zend_class_entry*

z   zval*

Z   zval**

http://blog.csdn.net/leonpengweicn/article/details/12946993?%3E, 补充资料:https://my.oschina.net/jackin/blog/172926
ZEND_API int call_user_function_ex(
    HashTable *function_table,
    zval **object_pp,
    zval *function_name,
    zval **retval_ptr_ptr,
    zend_uint param_count,
    zval **params[],
    int no_seperation,
    HashTable *symbol_table TSRMLS_DC);
params is an array of pointers to zval pointers. Note: this is _not_ a PHP/zval array, it is a C array. Example:

zval *foo; zval *bar; zval **params[2]; params[0] = &foo; params[1] = bar;]