Hi, I'm trying to write a function in an extension (using PHP_FUNCTION) that returns a value by reference. I have declared an arg info block (ZEND_BEGIN_ARG_INFO_EX) to tell the engine that I am returning a value by reference. Then to return the value, I first delete the old return value (zval_ptr_dtor(&return_value)), and then overwrite *return_value_ptr. This seems to work if the function is called from PHP.
However, when I try to call the function manually from another extension function (using call_user_function_ex), things break. After call_user_function_ex returns, I do get the right zval pointer, but its refcount and is_ref fields have been reset to 1 and 0. After some debugging it turned out that is this due to zend_call_function (in zend_execute_API.c). The relevant snippet is: if (EX(function_state).function->type == ZEND_USER_FUNCTION) { // ... } else { ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr); if (EX(function_state).function->common.scope) { EG(scope) = EX(function_state).function->common.scope; } ((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, EX(function_state).function->common.return_reference?fci->retval_ptr_ptr:NULL, (fci->object_pp?*fci->object_pp:NULL), 1 TSRMLS_CC); INIT_PZVAL(*fci->retval_ptr_ptr); } (in 5.2.2, line 982 and following). Note the last line in that else: after the function has been called, INIT_PZVAL is called on the return value of the function, overriding whatever refcount and is_ref I had set for the zval to be returned. How do I solve this problem? Thanks! Edsko -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php