I was surprised to find that my class entry failed when I tried to pass the 
class name as a parameter. Two common styles (char *myclassname = "myclass";
and (over-buffered) char myclassname[100] = "myclass";) both fail with
INIT_CLASS_ENTRY for a reason that becomes apparent when you look
at the source (interesting experience, having the source available!).

INIT_CLASS_ENTRY determines the classname length by sizeof(myclassname)
not strlen(myclassname), so the former char* returns 4, being the size of a 
pointer, and the latter returns 100, being the size of the buffer, neither 
being then intended reasonable size of the name as would have been determined
by strlen, here 7 ("myclass").

Consequently, a call to instantiate 'new myclass()' fails, with no such class 
name registered.

Maybe that's 'obvious' and I should have known better, but both buffers and
static (?) strings I thought were 'reasonable' and in normal use, so I thought 
I'd flag the issue.

(Interestingly, in zend_API.c, ZEND_API int zend_disable_class(char 
*class_name, uint class_name_length TSRMLS_DC) receives a char* for
class_name which it passes to INIT_CLASS_ENTRY, presumably without
ill-effect, and despite the issue above...)

Am I missing something, or is that simply a behaviour that's a) intentional,
or b) understood and just needs to be worked around.

Conundrum: I had assumed that to resolve this, I may need to set up an
'emalloc()' of the precise length required, but in fact this still does not 
resolve the issue, as the char* returned by the emalloc will be sizeof() = 4,
whatever the string.

Is there no way therefore to pass a variable length classname to a dynamic
class creation routine? Seems a little unlikely, but I can't see it in light 
of the above.

Guess I can ignore the INIT_CLASS_ENTRY macro, or let it run and then
post-assign the classname with appropriate length based on strlen() or
std::string.length().

Just a thought.

// Various formats tried:

  // char phpclassname[50] = "minicooper";
    // char *phpclassname = "minicooper";
    char phpclassname[11] = "minicooper"; // this works - exact + 1 for zero
    // char phpclassname[10] = "minicooper"; // this fails - insufficient 
bytes (to include terminating zero)
    // char phpclassname[12] = "minicooper"; // this fails - sizeof is 'too 
big' (one spare byte - buffer must be 'exact'
    // char phpclassname[50] = "minicooper"; // this fails  - ditto - too big
    // phpclassname[10] = '\0';    // this does not resolve 'too big' buffers
    // string spcname("minicooper"); // this does not work
   
        // Calls based on the above, as appropriate
    // INIT_CLASS_ENTRY(ce, spcname.c_str(), minicooper_class_functions);  
    INIT_CLASS_ENTRY(ce, phpclassname, minicooper_class_functions);
    // INIT_CLASS_ENTRY(ce, "minicooper", minicooper_class_functions); 

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to