Here's how I do that kind of thing.
The source code (Node.pl):
#!/usr/bin/perl
package Node; use strict; use warnings;
use Inline C => Config => BUILD_NOISY => 1;
use Inline C => <<'__EOI__', NAME => 'Node', CLEAN_AFTER_BUILD =>0, T
+YPEMAPS => 'Node.typemap';
#define CLASS "Node"
// XXX no children for now
typedef struct Node {
struct Node* parent;
SV* sv;
} Node;
Node *new( const char *classname ) {
Node *t;
Newx( t, 1, Node );
t->sv = newSViv( 0 );
return t;
}
// should NOT alter refcount
Node* set_parent( Node* self, Node* parent ) {
self->parent = parent;
return self;
}
Node* get_parent(Node* self) {
return self->parent;
}
// XXX get/set children deferred
void destroy_node(Node* self) {
Safefree(self);
}
__EOI__
sub DESTROY {
my $self = shift;
warn "destroying $self";
$self->destroy_node;
}
package main;
use Devel::Peek;
$|++;
my $node = Node->new();
my $parent = Node->new();
print "NODE: ";
Dump($node);
print "---\n";
print "PARENT: ";
Dump($parent);
print "---\n";
$node->set_parent($parent);
print "FROM FIELD: ";
print Dump($node->get_parent);
print "---\n";
The typemap (Node.typemap):
TYPEMAP
const char * T_PV
Node * O_OBJECT
U64 T_UV
U8 T_UV
U8 * T_PV
INPUT
O_OBJECT
if( sv_isobject($arg) && ( SvTYPE( SvRV($arg) ) == SVt_PVMG ) )
$var = INT2PTR( $type, SvIV( (SV*)SvRV( $arg ) ) );
else{
warn( \"${Package}::$func_name() -- $var is not a blessed
+SV reference\" );
XSRETURN_UNDEF;
}
OUTPUT
# The Perl object is blessed into 'CLASS', which should be a
# char* having the name of the package for the blessing.
O_OBJECT
sv_setref_pv( $arg, (char *)CLASS, (void*)$var );
The output from a run:
C:\test>Node.pl
NODE: SV = RV(0x35f17f0) at 0x35f17e0
REFCNT = 1
FLAGS = (PADMY,ROK)
RV = 0x19f070
SV = PVMG(0x35e6308) at 0x19f070
REFCNT = 1
FLAGS = (OBJECT,IOK,pIOK)
IV = 58154984
NV = 0
PV = 0
STASH = 0x1f6f48 "Node"
---
PARENT: SV = RV(0x35f1718) at 0x35f1708
REFCNT = 1
FLAGS = (PADMY,ROK)
RV = 0x3787a00
SV = PVMG(0x35e6368) at 0x3787a00
REFCNT = 1
FLAGS = (OBJECT,IOK,pIOK)
IV = 58163768
NV = 0
PV = 0
STASH = 0x1f6f48 "Node"
---
destroying Node=SCALAR(0x19ed58) at C:\test\Node.pl line 41.
FROM FIELD: SV = RV(0x19f098) at 0x19f088
REFCNT = 1
FLAGS = (TEMP,ROK)
RV = 0x19ed58
SV = PVMG(0x35e6278) at 0x19ed58
REFCNT = 1
FLAGS = (OBJECT,IOK,pIOK)
IV = 58163768
NV = 0
PV = 0
STASH = 0x1f6f48 "Node"
destroying Node=SCALAR(0x19ed58) at C:\test\Node.pl line 41.
---
destroying Node=SCALAR(0x3787a00) at C:\test\Node.pl line 41.