Well, it's been three weeks and I'm finally getting back to this. I think it's working fine, but I'm asking for a review to make sure I'm not doing anything stupid.
To review, I needed to track a parent object to manage reference counts. In perl, it might look like: my $parent = Foo->new; my @list = $parent->list; print list[0]->Name; # C call. where I don't want $parent destroyed until all elements of @list are gone. So, with your help Tassilo, I made each element of @list a struct that contains both the pointer to the $parent SV and also the pointer I need for calling the Name() function in my C code. Upon DESTROY I free that struct and decrement that parent's ref count. I have two questions, and a comment: First, I'm not clear if I'm dealing with the Perl stack correctly. So, could you (or someone) look that over, please? Second, how do I make sure memory is going away like I expect? Is there a tool that will tell me if I've got any allocated SVs when my test program wants to exit? Trying to avoid any leaks, of course. And my comment: I had wanted to keep my XSUB code clean by using typemaps -- that is, have method calls look only like: const char * SwishMetaName( meta ) SW_META meta That turned out to be trivial using a typemap and a PREFIX. Code: Back to my first question. In my XSUB I have one function call another function that does the work using call_pv(). I'll just show the code, but what I'm not clear on is if I'm dealing with the stack correctly. I'm *not* using the return value of call_pv(), but I wonder if I need to extend the stack before returning. I'm using XPUSHs, but I'm not clear if that's enough when one function calls another. In short -- I just want to make sure I've got the stack correctly handled. /* At the top of the .xs file -- container object */ typedef struct { SV *handle_sv; /* Parent SV for DESTROY */ SW_META meta; /* meta description C pointer */ } META_OBJ; /* SW_HANDLE is a typemap of O_OBJECT, so that gets me the C pointer */ void SwishMetaList( swish_handle, index_name ) SW_HANDLE swish_handle char *index_name PREINIT: SWISH_META_LIST meta_list; PPCODE: /* Grab the list of pointers */ meta_list = SwishMetaList( swish_handle, index_name ); PUSHMARK(SP) ; XPUSHs( (SV *)swish_handle ); XPUSHs( (SV *)meta_list ); XPUSHs( (SV *)"SWISH::API::MetaName"); PUTBACK ; /* lets perl know how many parameters are here */ call_pv("SWISH::API::push_meta_list", G_ARRAY ); SPAGAIN; Do I need to check the return value of call_pv() and use that to set the stack size? The perl stack is somewhat, no, mostly black magic to me. Below is the code that does the real work. It's called by four XSUB functions like above. Do I need to call XSRETURN(n) where n is the number of elements on the array when exiting the function? The function SwishGetRefPtr() returns the SV associated to the swish_handle, if you are wondering. void push_meta_list( s_handle, m_list, m_class ) SV *s_handle SV *m_list SV *m_class PREINIT: SW_HANDLE swish_handle; SWISH_META_LIST meta_list; char *class; PPCODE: class = (char *)m_class; swish_handle = (SW_HANDLE)s_handle; meta_list = (SWISH_META_LIST)m_list; /* Make sure a list is returned and it's not empty */ if ( !meta_list || !*meta_list ) XSRETURN_EMPTY; while ( *meta_list ) { /* Create a new structure for storing the meta description and the parent SV */ META_OBJ *object = (META_OBJ *)safemalloc(sizeof(META_OBJ)); /* Store the meta entry */ object->meta = *meta_list; /* Store the and bump the swish_handle SV */ object->handle_sv = (SV *)SwishGetRefPtr( swish_handle ); SvREFCNT_inc( object->handle_sv ); /* And create the Perl object and assign the object to it */ SV *o = sv_newmortal(); sv_setref_pv( o, class, (void *)object ); /* and push onto list */ XPUSHs( o ); meta_list++; } Then later on, here's the class. META_OBJ is just a O_OBJECT typemap so that just give me the structure. SW_META is a slightly modified typemap to give me the ->meta element from that structure, which makes my method calls very easy to write in the XSUB. MODULE = SWISH::API PACKAGE = SWISH::API::MetaName PREFIX = SwishMeta void DESTROY ( self ) META_OBJ *self CODE: SvREFCNT_dec( self->handle_sv ); safefree( self ); const char * SwishMetaName( meta ) SW_META meta int SwishMetaType( meta ) SW_META meta int SwishMetaID( meta ) SW_META meta -- Bill Moseley [EMAIL PROTECTED]