Re: Calling constructor with xsub

2002-10-13 Thread Nick Ing-Simmons

Bill Moseley [EMAIL PROTECTED] writes:

PUSHMARK;
XPUSHs(swish_handle_sv);
XPUSHs(query_sv);
PUTBACK;
call_method(new,G_SCALAR);
SPAGAIN;
search_object_sv = POPs;

I think that last line is where I'm going to get stuck.  See below.


Which suggests that using this signature would be better:

SW_SEARCH
new(CLASS, swish_handle, optional_string )
char *CLASS
SV *swish_handle

As it avoids the need to back-convert the SW_HANDLE to an SV.

But in that SWISH::API::Search::new function I need to pass SW_HANDLE into
my C code, so seems like I'd need to pass around SW_HANDLE.  

You are still passing it around. You are just not un-packing it in the 
outer call.

But maybe I'm
misunderstanding your example.

Let's see if I'm following.  Say I will create two objects.

  my $handle = SWISH::API-new( index.file );

Fine. So now $handle is an SV * with a SW_HANDLE hidden inside.


  # Create a search object based on the handle object.
  my $search = SWISH::API::Search-new( $handle, $query );

These constructors seem simple enough.

MODULE = SWISH::APIPACKAGE = SWISH::API

SW_HANDLE
new(CLASS, index_file_list )
char *CLASS
char *index_file_list
CODE:
/* SwishInit is in the C library */
RETVAL = SwishInit( index_file_list );
OUTPUT:
RETVAL

So that new returns a SW_HANDLE - fine.


MODULE = SWISH::APIPACKAGE = SWISH::API::Search

SW_SEARCH
new(CLASS, swish_handle, query )
char  *CLASS
SW_HANDLE  swish_handle
 /* So we are going to find the SW_HANDLE inside the passed arg */
char  *query

CODE:
/* New_Search_Object is in the C library */
RETVAL = New_Search_Object( swish_handle, query );
OUTPUT:
RETVAL

Now, since you always need to pass a handle to create a search object, I
decided to make the API look more like:

  my $handle = SWISH::API-new( index.file );

  #my $search = SWISH::API::Search-new( $handle, $query );
  my $search = $handle-New_Search_Object( $query );

So back in the SWISH::API package:

Not quite right - see non-quoted bits added.


SV *
New_Search_Object(self, query)
 SV *   self;   /* we want an SV for the handle so ... */
char *query/* If you had query as an SV too ... */

CODE:
PUSHMARK;
XPUSHs(sv_2mortal(newSVpv(SWISH::API::Search,18));
 XPUHSs(self);  /* ... we can pass the handle to new */
XPUSHs(sv_2mortal(newSVpv(query,0)); /* ... we could avoid convert to/from 
string */
PUTBACK;
call_method(new,G_SCALAR);
SPAGAIN;
RETVAL = POPs;
OUTPUT:
RETVAL

That throws me off a bit since SWISH::API::Search::new returns a SW_SEARCH
object yet that returns a SV *.

Which contains the SW_SEARCH hidden inside by the output typemap of 
the new XSUB.

Another way to look at this is suppose you had written New_Search_Object
as perl code - e.g. in your .pm file you could have had:

package SWISH::API;

sub New_Search_Object
{
 my ($handle,$query) = @_;
 return SWISH::API::Search-new($handle,$query);
}

The modified XS code above is doing the same - calling the inner 
method but just using/returning SVs without looking inside.


BTW, in my previous message I had a typemap of:

TYPEMAP
SW_HANDLE *  O_OBJECT
SW_SEARCH *  O_OBJECT
SW_RESULTS *  O_OBJECT
SW_RESULT *   O_OBJECT

But SW_* are already pointers to a structure so I can just use this.  Correct?

TYPEMAP
SW_HANDLE   O_OBJECT
SW_SEARCH   O_OBJECT
SW_RESULTS  O_OBJECT
SW_RESULT   O_OBJECT

I apologize for being so lame at this stuff! ;)  XS sometimes makes me feel
like that guy on the cover of Extending and Embedding Perl...

Thanks,
-- 
Nick Ing-Simmons
http://www.ni-s.u-net.com/




Re: Calling constructor with xsub

2002-10-13 Thread Nick Ing-Simmons

Bill Moseley [EMAIL PROTECTED] writes:

I also realize that in my xsub there's no real point in calling
SWISH::API::Search::new just to create the object as New_Search_Object can
just call the C code to fetch the new struct returned as an object.  I
think I could do that directly with sv_setref_pv and avoid using
call_method.  I really don't need a new() method in the
Swish::API::Seach package since it will never be called from perl.

The details of using sv_setref_pv are a bit clowdy right now, but I intend
to read a bit more as soon as I get some time.

sv_setref_pv gives me a headache too. 
(FWIW most of my objects use sv_setref_iv as I store pointers 
to C/C++ objects in IV rather than PV - but you need to be consistent.)

But what you are saying can (I think) be expressed as XS ;-) and so 
let normal typemap magic do the blessing

Something like: 

MODULE = SWISH::APIPACKAGE = SWISH::API

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

INIT: 
char *CLASS = SWISH::API::Search;

CODE:
RETVAL = New_Search_Object( swish_handle, query )

OUTPUT:
RETVAL

The INIT:/CLASS is just there so it is in scope (I hope) when typemap for 
OUTPUT does its thing to bless the object.


-- 
Nick Ing-Simmons
http://www.ni-s.u-net.com/




Re: Calling constructor with xsub

2002-10-13 Thread Bill Moseley

At 04:59 PM 10/13/02 +0100, Nick Ing-Simmons wrote:

sv_setref_pv gives me a headache too. 
(FWIW most of my objects use sv_setref_iv as I store pointers 
to C/C++ objects in IV rather than PV - but you need to be consistent.)

I thought sv_setref_pv did store the pointer as an IV.  The typemap uses
setref_pv on output and for input:

$var = ($type)SvIV((SV*)SvRV( $arg ));

which is fetching the pointer from the IV, right?


But what you are saying can (I think) be expressed as XS ;-) and so 
let normal typemap magic do the blessing

Something like: 

MODULE = SWISH::APIPACKAGE = SWISH::API

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

INIT: 
char *CLASS = SWISH::API::Search;

Well, gee.  That makes things easy.  And since the signature is the same as
my library function I'll bet it would even work without the CODE: and
OUTPUT: sections.  I need PREINIT so that CLASS is declared before the
typemap code is inserted in the output, though.

Wow, thanks for that bit of help!


-- 
Bill Moseley
mailto:[EMAIL PROTECTED]