Re: repost: return_value getting corrupted in extension

From: Date: Wed, 12 Feb 2003 08:39:47 +0000
Subject: Re: repost: return_value getting corrupted in extension
References: 1 2  Groups: php.dev 
Request: Send a blank email to php-dev+get-94189@lists.php.net to get a copy of this message
On Tue, 2003-02-11 at 16:00, Wez Furlong wrote: > No offense, but this is really quite a useless problem report. > You are not showing any of the zend API that you use to create the > object, so how can we help you? No offense taken. I hoped that showing the php_var_dump() would be evidence enough that things are being properly initialized, and didn't want to post such a long question that no one would bother to read it. It seemed to me that if I followed the instructions (as in the very slim and out-of-date zend API docs, and with the help of those who have posted comments therein) to initialize and setup the desired return_value, that it should be returned to my script. Here, then, is how I am initializing the given data. This is the object constructor. You will see below how it is used. /* {{{ eo_table class declaration */ /* zend_function entry list resides in eo_gateway.c */ PHP_FUNCTION(eo_table) { /* define and initialize the object members */ printf("\tin eo_table constructor now!\n"); add_property_string(this_ptr, "serverId", "", TRUE); add_property_long(this_ptr, "rows", 0); add_property_long(this_ptr, "cols", 0); add_property_bool(this_ptr, "namedCols", FALSE); add_property_string(this_ptr, "errorText", "", TRUE); add_property_string(this_ptr, "errorItem", "", TRUE); add_property_long(this_ptr, "errorId", 0); add_property_long(this_ptr, "flags", 0); add_property_null(this_ptr, "colNames"); add_property_null(this_ptr, "table"); } /* end eo_table */ /* }}} */ Here are the bits from eo_gateway.c. I hope I've pasted them all: zend_class_entry *eo_table_class_entry_ptr_global; static zend_class_entry *eo_table_class_entry_ptr; static zend_function_entry eo_table_class_functions[] = { ZEND_FE(eo_table, NULL) ZEND_FE(eo_table_error_dump, NULL) ZEND_FALIAS(error_dump, eo_table_error_dump, NULL) {NULL, NULL, NULL} }; /* {{{ PHP_MINIT_FUNCTION */ PHP_MINIT_FUNCTION(eo_gateway) { zend_class_entry eo_table_class_entry; INIT_CLASS_ENTRY(eo_table_class_entry, "eo_table", eo_table_class_functions); eo_table_class_entry_ptr = zend_register_internal_class(&eo_table_class_entry TSRMLS_CC); return SUCCESS; } /* end PHP_MINIT_FUNCTION */ /* }}} */ /* {{{ PHP_RINIT_FUNCTION */ PHP_RINIT_FUNCTION(eo_gateway) { eo_table_class_entry_ptr_global = eo_table_class_entry_ptr; return SUCCESS; } /* }}} */ In the source file in which I am actually creating and intializing my object, I have declared: extern zend_class_entry *eo_table_class_entry_ptr_global; Here, within a function called getData(), which is called by the getDataReply() function mentioned in my initial post, we create the object: /* initialize return_value to be a table object */ printf("\n\tCreating the return_value object (eo_table)\n"); object_init_ex(return_value, eo_table_class_entry_ptr_global); /* call the table constructor */ call_object_constructor(return_value, "eo_table"); php_var_dump(&return_value, 1 TSRMLS_CC); Here, from another source file, is the definition of call_object_constructor(): /* {{{ void call_object_constructor() */ void call_object_constructor(zval* object, char* object_name) { /* constructor function name */ zval* ctor_fn; /* constructor return value (required but not used) */ zval* ctor_retval; printf("\tcalling constructor for: '%s'\n", object_name); /* specify the constructor/object name */ MAKE_STD_ZVAL(ctor_fn); ZVAL_STRING(ctor_fn, object_name, TRUE); MAKE_STD_ZVAL(ctor_retval); /* call the constructor */ if ( call_user_function(NULL, &object, ctor_fn, ctor_retval, 0, NULL) != SUCCESS ) { php_error(E_ERROR, "Could not call object constructor '%s'", object_name); } printf("\tctor_retval is %s\n", zend_zval_type_name(ctor_retval)); /* clean up! */ zval_dtor(ctor_fn); efree(ctor_fn); efree(ctor_retval); } // end call_object_constructor() /* }}} */ I believe that is all the relevant code, and though I have removed some stuff for clarity and privacy, none of it directly affects any Zend objects or variables. > Hints: make sure that your zvals are correctly initialized (there are > some big differences between ALLOC_ZVAL and MAKE_STD_ZVAL). One resets the refcount and the is_ref flag, the other doesn't. All the variables I'm dealing with are "fresh", not references to pre-existing zvals. Note also that the variables which are getting corrupted are simple strings, not even zvals. Here is how I'm setting the value of serverId, which is one of those getting corrupted: add_property_string(return_value, "serverId", serverId, TRUE); efree(serverId); I don't believe I'm ever running MAKE_STD_ZVAL on return_value, but I don't think the examples didn't do that either. It's already initialized by default, correct? > Other things to try are looking at other extensions that create objects. > In the 4.3 release, the user-space streams creates objects and call their > constructors, so take a look at that code for some hints. I have 4.3 on the other dev server, I will check that out. > If you are returning strings, make sure that any that need to be > duplicated are duplicated etc. etc. > > Using the source is your best option if you don't want (or are not > allowed) to show us your source. I've shown you what I can, I don't think you want to see it all :) > The zend api docs http://www.php.net/manual/en/zend.php, > although not > complete, should be good enough for what you need to do. Unfortunately, I couldn't have gotten near to what I've been able to do without pouring through the Zend, PHP, extension source code, and newsgroup posts. I tried everything I could before posting. Thanks in advance for any insights you can give. This is really frustrating. If you want to know how I am doing anything else, let me know. Eric -- This message was created in a Microsoft-free computing environment.

« previous php.dev (#94189) next »