Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Returning a reference to an existing C++ object as a reference

Reply
Thread Tools

Returning a reference to an existing C++ object as a reference

 
 
JustMe
Guest
Posts: n/a
 
      08-29-2003
Hi All,

Given:

package x;

sub new { return bless {}, $_[0]; }

#-- callback() is call by the C++ class (reader_as_cpp_object)
#-- whenever an event is detected.

sub callback {
my ($self, $ref_to_an_event_object) = @_;
print $ref_to_an_event_object->data();
}

package main;

use reader_as_cpp_object;

my $x = x->new();
my $reader = reader_as_cpp_object->new($x)

$reader->read( 'afile.txt' ) # Reader is a reference to a C++ class


I've got the callback working just fine. The problem I can't seem to
solve, is how to pass the sub callback() a reference to a C++ object
that was created by the C++ object reader_as_cpp_object.

All of the examples I've seen assume that object is create via an
action from the perl program. E.g.

my $object = cow->new();


I've read perlgut, perlapi, perlxs, perlxstut, cookbookA and
cookbookB, and googled all day and I'm still no closer to a solution.

Anyone have an example and or suggestion?

Thanks

Eric
 
Reply With Quote
 
 
 
 
Tassilo v. Parseval
Guest
Posts: n/a
 
      08-29-2003
Also sprach JustMe:

> Given:
>
> package x;
>
> sub new { return bless {}, $_[0]; }
>
> #-- callback() is call by the C++ class (reader_as_cpp_object)
> #-- whenever an event is detected.
>
> sub callback {
> my ($self, $ref_to_an_event_object) = @_;
> print $ref_to_an_event_object->data();
> }
>
> package main;
>
> use reader_as_cpp_object;
>
> my $x = x->new();
> my $reader = reader_as_cpp_object->new($x)
>
> $reader->read( 'afile.txt' ) # Reader is a reference to a C++ class
>
>
> I've got the callback working just fine. The problem I can't seem to
> solve, is how to pass the sub callback() a reference to a C++ object
> that was created by the C++ object reader_as_cpp_object.


Can you be more specific? You want $ref_to_an_event_object to
contain a pointer to a C++ object? This is easy. Do something like this
in your callback:

OBJECT *obj; // obj is the C++ object

...
SV *ref_to_obj = sv_newmortal();
sv_setref_pv(ref_to_object, "Class::Of::Reader", (void*)obj);

XPUSHs(ref_to_object); // push onto stack to pass to Perl callback
...

Your callback will now receive a scalar variable with an integer in it.
This integer is the address of the C++ object. To de-reference the
pointer and get the object back, you do:

OBJECT *obj = (OBJECT*)SvIV((SV*)SvRV(ref_to_object));

Usually, you put such things into a typemap file to let these
conversions happen authomatically:

# mapping from C++ objects to INPUT/OUTPUT objects
OBJECT * O_OBJECT

OUTPUT
O_OBJECT
sv_setref_pv( $arg, CLASS, (void*)$var );

INPUT
O_OBJECT
if( sv_isobject($arg) && (SvTYPE(SvRV($arg)) == SVt_PVMG) )
$var = ($type)SvIV((SV*)SvRV( $arg ));
else{
warn( \"${Package}::$func_name() -- $var is not a blessed SV reference\" );
XSRETURN_UNDEF;
}

And now you can use that in your XSUBS very conveniently:

OBJECT *
function (obj)
OBJECT *obj;
PREINIT:
OBJECT *new_object;
CODE:
...
new_object = new OBJECT (args,...);
RETVAL = new_object;
OUTPUT:
RETVAL

So INPUT typemap kicks in when you pass your XSUB an appropriate
argument. 'OBJECT *obj' is such an argument and now Perl will convert
the SV* it receives into a pointer to OBJECT according to the
INPUT/O_OBJECT typemap. When returning 'OBJECT*', OUTPUT/O_OBJECT turns
a C++ object into a SV*.

When calling a Perl-callback however, you have to do this conversion
manually as I showed further above. You just copy the pointer (casted to
(void*) into an SV using sv_setref_pv(), at the same time blessing the
scalar variable into the appropriate package that should handle objects
of this type. Since your function read() operates on the C++ object,
bless it into the package where this method is defined. Use the INPUT
there and your Perl object is turned into a C++ again.

> I've read perlgut, perlapi, perlxs, perlxstut, cookbookA and
> cookbookB, and googled all day and I'm still no closer to a solution.


I was just about to recommend cookbookA and cookbookB, but you have
already read that. It's not exactly full of verbose explanations, it
just gives a few examples. Do they make more sense now? You could try to
re-read perlxs.pod, section "Using XS with C++".

Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus}) !JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Existing Dll - using Functions from an existing dll Tristin.Colby@gmail.com Ruby 0 02-05-2008 07:38 PM
"Object reference not set to an instance of an object" Weird thing happens with reference a link nguyentrongkha@gmail.com ASP .Net 1 09-20-2007 09:46 PM
Why no existing Java type to existing XML schema binding support? nrm Java 3 04-10-2006 04:52 PM
Returning a reference to an object PGR Java 6 01-04-2006 12:08 AM
using a String to reference an already existing Object Andrew Purser Java 3 07-26-2004 08:53 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57