php 使用zend_call_function()时发生分段错误

bf1o4zei  于 2023-02-03  发布在  PHP
关注(0)|答案(1)|浏览(125)

我正在尝试使用PHP的Zend引擎将一个C库围绕一个PHP类进行变形。该类的构造函数应该接受一个字符串和一个函数指针。我可以从__construct参数中获取字符串值并打印它们。但是当我获取函数并尝试在类的构造函数中运行时,我得到了一个segfault错误。
基本上,最终结果应该是这样的:

class TestClass
{
   function __construct(callable: $callBack, string: $name);
}

(当然,类中还有其他方法,但我对它们没有意见)。C扩展看起来如下:

PHP_METHOD(TestClass, __construct)
{
    zend_string* name;
    zend_fcall_info fci;
    zend_fcall_info_cache fci_cache;
    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "fS", &fci, &fci_cache, &name) == FAILURE)
        return;
    php_printf("name: %s\n", ZSTR_VAL(name));
    if (zend_call_function(&fci, &fci_cache TSRMLS_CC) == SUCCESS) {
        php_printf("Called");
    }
    zval* obj = getThis();
    test_class_t* intern;
    intern = Z_TSTOBJ_P(obj);
    php_printf("Constructor\n");
    zend_string_release(name);
    if (fci.params)
        efree(fci.params);
}

注解掉zend_call_function后没有出现Segfault,我用的是7.2.19和C99,有没有办法解决这个问题?
谢谢

rvpgvaaj

rvpgvaaj1#

在调用函数之前,必须为函数的返回值指定一个zval,还必须指定要传递的参数的数量:

zval retval;
fci.retval = &retval;
fci.param_count = 0;
// Use zend_call_function()
zval_ptr_dtor(&retval);

要使用参数,必须分配一个zvals数组(堆栈或堆)来保存要传递的值。一个简单的示例如下:

zval args[2];
ZVAL_LONG(&args[0], 1);
ZVAL_LONG(&args[1], 2);
fci.params = args;
fci.param_count = 2;
// Use zend_call_function() here.
zval_ptr_dtor(&args[0]);
zval_ptr_dtor(&args[1]);

在堆分配的情况下:

zval *args = emalloc(2 * sizeof(zval));
// Assign, call and dtor as in previous example.
efree(args);

相关问题