On Mon, 17 Mar 2003, Nick Ing-Simmons wrote:

> Bill Moseley <[EMAIL PROTECTED]> writes:
> All you really want to do is increment the SvREFCNT of the parent object
> for the duration. You can do that my hand and then (if you cannot already
> locate it) save pointer to search object's SV in the C struct.
> 
> Does that help ?

Yes, kind of.  I know I need to do that, but I'm such a infrequent XS user
the implementation is escaping me.

So in the C library I'll need to add a place to hold the address of the
parent (perl) object's address, correct?  I'll also need to add a method
in the C library to set and fetch the Perl scalar's address.  (The XS code
doesn't know the members of the C struct, only void * is passed outside of
the library.)

But after that I'm stuck on the XS code.  It's those damn typemaps that
make things so easy that is now confusing me.

The current code is easy (thanks to the typemaps):

SW_SEARCH
New_Search_Object(swish_handle, query = NULL)
    SW_HANDLE swish_handle
    char *query

    PREINIT:
        char * CLASS = "SWISH::API::Search";


So, I'll need to 

  1) SvREFCNT_inc() on the "parent" swish_handle

  2) save away the address of the swish_handle 
     after calling New_Search_Object

  3) on destroy first call SvREFCNT_dec() on the parent then
     call the code to free the SW_SEARCH object.

Hum, this doesn't look right, but I'll give it a shot:

MODULE = SWISH::API        PACKAGE = SWISH::API    PREFIX = Swish

SW_SEARCH
New_Search_Object(swish_handle, query = NULL)
    SW_HANDLE swish_handle
    char *query
    void *parent = ST(0);

    PREINIT:
        char * CLASS = "SWISH::API::Search";
    CODE:
        SvREFCNT_inc( ST(0) );

        RETVAL = New_Search_Object( swish_handle, query );
        Search_parent( RETVAL, parent );
    OUTPUT:
        RETVAL



MODULE = SWISH::API        PACKAGE = SWISH::API::Search    PREFIX = Swish

void
DESTROY(search)
    SW_SEARCH search

    PREINIT:
        SV *parent;  
    CODE:
        parent =  (SV *)Search_parent( search, NULL );
        Free_Search_Object( search );
        SvREFCNT_dec( parent );


Can someone give me an example how to do this all in the XS?  I imagine
I'd need to create a two element array holding the object returned from
the C library and a reference to the parent object.

But then in all my methods on the object I'd need to de-reference the
object.  For example in a method like:

void
SwishSetQuery(search,query)
    SW_SEARCH search
    char * query

search would be an array reference so I'd need to call 

   SwishSetQuery( search[0], query );

Could a typemap solve that?

The reason I might want to do it in the XS code is that swish (a search
engine) can generate a large number of results, and it would be nice to
keep swish's "result" structure small as possible (i.e. not adding a new
element just to hold a perl SV*.  A query might create 100,000 "result"
records in the C library, but the user code might only want to see a page
of 10 at a time, and those are the only that need the refcount managed.

Sorry for the basic question.  I just don't use XS enough.

Thanks,


-- 
Bill Moseley [EMAIL PROTECTED]


Reply via email to