(Apologies if this is the wrong list or if the answer to this has
escaped my searches, but I'm at my wit's end at the moment).
I'm trying to get a libical binding going for PHP (v4.3.2, with plans to
port to 5.0 as soon as it works with v4.3.x). At the moment,
this PHP code works:
$x = icalcomponent_new_vcalendar();
$y = icalcomponent_new_vevent();
$x->add_component($y);
but this fails:
$x = icalcomponent_new_vcalendar();
$x->add_component(icalcomponent_new_vevent());
Both icalcomponent_new_vcalendar() and icalcomponent_new_vevent() return
icalcomponent classes from the extension. Icalcomponent has one
data member ("resource") holding an icalcomponent *, and a class entry
containing a list of functions (such as "add_component") that can be
used to manipulate the component.
I've attempted to debug this - in the failing case the vcalendar
component and the vevent component are created correctly, but when
icalcomponent_new_vevent() returns something happens so that add_component
isn't being found properly:
$ gdb ../../../sapi/cli/php core
GNU gdb 5.3
Core was generated by `../../../sapi/cli/php t1.php'.
Program terminated with signal 11, Segmentation fault.
#0 call_overloaded_function (T=0xa0dc624c, arg_count=1,
return_value=0x81d86b4)
at /tmp/new_installation/php-4.3.2-devel/Zend/zend_execute.c:966
966 ce = Z_OBJCE_P(T->EA.data.overloaded_element.object);
(gdb) where
#0 call_overloaded_function (T=0xa0dc624c, arg_count=1,
return_value=0x81d86b4)
at /tmp/new_installation/php-4.3.2-devel/Zend/zend_execute.c:966
#1 0x081492ea in execute (op_array=0x81d416c)
at /tmp/new_installation/php-4.3.2-devel/Zend/zend_execute.c:1672
#2 0x0813cbf8 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
at /tmp/new_installation/php-4.3.2-devel/Zend/zend.c:869
#3 0x08117630 in php_execute_script (primary_file=0xbffff460)
at /tmp/new_installation/php-4.3.2-devel/main/main.c:1671
#4 0x0814d986 in main (argc=2, argv=0xbffff4f4)
at /tmp/new_installation/php-4.3.2-devel/sapi/cli/php_cli.c:806
#5 0x4010af64 in __libc_start_main (main=0x814d1d0 <main>, argc=2,
ubp_av=0x0, init=0x8066d68 <_init>, fini=0x1, rtld_fini=0x81d84a0,
stack_end=0x807e0b0) at ../sysdeps/generic/libc-start.c:144
(In the call_overloaded_function frame, the T parameter pointer is
invalid).
This is the relevant code that is being called in the extension; perhaps
somewhere I am not constructing/returning an icalcomponent class zval
properly?
static void
icalcomponent_new_return(zval *rv, icalcomponent *icc)
{
zend_class_entry *ce, icalcomponent_entry;
zval *res;
int resid;
INIT_CLASS_ENTRY(icalcomponent_entry, "icalcomponent", icalcomponenttype_functions);
ce = zend_register_internal_class(&icalcomponent_entry TSRMLS_CC);
object_init_ex(rv, ce);
MAKE_STD_ZVAL(res);
resid = ZEND_REGISTER_RESOURCE(res, icc, icalcomponent_resource_id);
add_property_resource(rv, "resource", resid);
}
static ZEND_FUNCTION(icalcomponent_new_vcalendar)
{
if(ZEND_NUM_ARGS() != 0) WRONG_PARAM_COUNT;
icalcomponent_new_return(return_value, icalcomponent_new_vcalendar());
}
static ZEND_FUNCTION(icalcomponent_new_vevent)
{
if(ZEND_NUM_ARGS() != 0) WRONG_PARAM_COUNT;
icalcomponent_new_return(return_value, icalcomponent_new_vevent());
}
static ZEND_NAMED_FUNCTION(zif_icalcomponent_add_component)
{
zval **entry, *icc_obj;
zend_class_entry icalcomponenttype_entry;
icalcomponent *icc = NULL, *child = NULL;
if(ZEND_NUM_ARGS() != 1) WRONG_PARAM_COUNT;
INIT_CLASS_ENTRY(icalcomponenttype_entry, "icalcomponent", icalcomponenttype_functions);
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o",
&icc_obj) == FAILURE)
return;
if(zend_hash_find(HASH_OF(getThis()), "resource", sizeof("resource"), (void **)&entry) == SUCCESS && Z_TYPE_PP(entry) == IS_RESOURCE)
ZEND_FETCH_RESOURCE(icc, icalcomponent *, entry, -1, ICALCOMPONENT_RESOURCE, icalcomponent_resource_id);
if(!icc || !icalcomponent_isa_component(icc) || !icalcomponent_is_valid(icc))
return;
if(zend_hash_find(HASH_OF(icc_obj), "resource", sizeof("resource"), (void **)&entry) == SUCCESS && Z_TYPE_PP(entry) == IS_RESOURCE)
ZEND_FETCH_RESOURCE(child, icalcomponent *, entry, -1, ICALCOMPONENT_RESOURCE, icalcomponent_resource_id);
if(!child || !icalcomponent_isa_component(child) || !icalcomponent_is_valid(child))
return;
icalcomponent_add_component(icc, child);
}
Any help would be appreciated. Thanks in advance.
-Bob
Please disregard this, I found the problem - namely,
zend_register_internal_class should be called once on module
initialization per internal class, not once per class instantiation.
-Bob
I'm trying to get a libical binding going for PHP (v4.3.2, with plans to
port to 5.0 as soon as it works with v4.3.x). At the moment,
this PHP code works:$x = icalcomponent_new_vcalendar();
$y = icalcomponent_new_vevent();
$x->add_component($y);but this fails:
$x = icalcomponent_new_vcalendar();
$x->add_component(icalcomponent_new_vevent());Both icalcomponent_new_vcalendar() and icalcomponent_new_vevent() return
icalcomponent classes from the extension. Icalcomponent has one
data member ("resource") holding an icalcomponent *, and a class entry
containing a list of functions (such as "add_component") that can be
used to manipulate the component.I've attempted to debug this - in the failing case the vcalendar
component and the vevent component are created correctly, but when
icalcomponent_new_vevent() returns something happens so that add_component
isn't being found properly:$ gdb ../../../sapi/cli/php core
GNU gdb 5.3
Core was generated by `../../../sapi/cli/php t1.php'.
Program terminated with signal 11, Segmentation fault.
#0 call_overloaded_function (T=0xa0dc624c, arg_count=1,
return_value=0x81d86b4)
at /tmp/new_installation/php-4.3.2-devel/Zend/zend_execute.c:966
966 ce = Z_OBJCE_P(T->EA.data.overloaded_element.object);
(gdb) where
#0 call_overloaded_function (T=0xa0dc624c, arg_count=1,
return_value=0x81d86b4)
at /tmp/new_installation/php-4.3.2-devel/Zend/zend_execute.c:966
#1 0x081492ea in execute (op_array=0x81d416c)
at /tmp/new_installation/php-4.3.2-devel/Zend/zend_execute.c:1672
#2 0x0813cbf8 in zend_execute_scripts (type=8, retval=0x0, file_count=3)
at /tmp/new_installation/php-4.3.2-devel/Zend/zend.c:869
#3 0x08117630 in php_execute_script (primary_file=0xbffff460)
at /tmp/new_installation/php-4.3.2-devel/main/main.c:1671
#4 0x0814d986 in main (argc=2, argv=0xbffff4f4)
at /tmp/new_installation/php-4.3.2-devel/sapi/cli/php_cli.c:806
#5 0x4010af64 in __libc_start_main (main=0x814d1d0 <main>, argc=2,
ubp_av=0x0, init=0x8066d68 <_init>, fini=0x1, rtld_fini=0x81d84a0,
stack_end=0x807e0b0) at ../sysdeps/generic/libc-start.c:144(In the call_overloaded_function frame, the T parameter pointer is
invalid).This is the relevant code that is being called in the extension; perhaps
somewhere I am not constructing/returning an icalcomponent class zval
properly?static void
icalcomponent_new_return(zval *rv, icalcomponent *icc)
{
zend_class_entry *ce, icalcomponent_entry;
zval *res;
int resid;INIT_CLASS_ENTRY(icalcomponent_entry, "icalcomponent", icalcomponenttype_functions);
ce = zend_register_internal_class(&icalcomponent_entry TSRMLS_CC);
object_init_ex(rv, ce);MAKE_STD_ZVAL(res);
resid = ZEND_REGISTER_RESOURCE(res, icc, icalcomponent_resource_id);
add_property_resource(rv, "resource", resid);
}static ZEND_FUNCTION(icalcomponent_new_vcalendar)
{
if(ZEND_NUM_ARGS() != 0) WRONG_PARAM_COUNT;
icalcomponent_new_return(return_value, icalcomponent_new_vcalendar());
}static ZEND_FUNCTION(icalcomponent_new_vevent)
{
if(ZEND_NUM_ARGS() != 0) WRONG_PARAM_COUNT;
icalcomponent_new_return(return_value, icalcomponent_new_vevent());
}static ZEND_NAMED_FUNCTION(zif_icalcomponent_add_component)
{
zval **entry, *icc_obj;
zend_class_entry icalcomponenttype_entry;
icalcomponent *icc = NULL, *child = NULL;if(ZEND_NUM_ARGS() != 1) WRONG_PARAM_COUNT;
INIT_CLASS_ENTRY(icalcomponenttype_entry, "icalcomponent", icalcomponenttype_functions);
if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "o",
&icc_obj) == FAILURE)
return;if(zend_hash_find(HASH_OF(getThis()), "resource", sizeof("resource"), (void **)&entry) == SUCCESS && Z_TYPE_PP(entry) == IS_RESOURCE)
ZEND_FETCH_RESOURCE(icc, icalcomponent *, entry, -1, ICALCOMPONENT_RESOURCE, icalcomponent_resource_id);if(!icc || !icalcomponent_isa_component(icc) || !icalcomponent_is_valid(icc))
return;if(zend_hash_find(HASH_OF(icc_obj), "resource", sizeof("resource"), (void **)&entry) == SUCCESS && Z_TYPE_PP(entry) == IS_RESOURCE)
ZEND_FETCH_RESOURCE(child, icalcomponent *, entry, -1, ICALCOMPONENT_RESOURCE, icalcomponent_resource_id);if(!child || !icalcomponent_isa_component(child) || !icalcomponent_is_valid(child))
return;icalcomponent_add_component(icc, child);
}Any help would be appreciated. Thanks in advance.
-Bob
--
<!DSPAM:3f3a5e2f204661244910416