use strict; use warnings; my $parent = Node->new('Parent'); my $child = Node->new('Child'); # Should print 'Parent' print $child->set_parent($parent)->get_parent->get_name, "\n"; $child->set_name('New name'); # Should print 'New name' print $child->get_name, "\n"; # At end, should see # Freeing 0xnnnnnnn (New name) # Freeing 0xnnnnnnn (Parent) ################################# package Node; use Inline Config => CLEAN_AFTER_BUILD => 0, PRINT_INFO => 1; use Inline C => q{ typedef struct { char* name; double branch_length; SV* parent; struct Node* previous_sister; struct Node* next_sister; struct Node* first_daughter; struct Node* last_daughter; } Node; SV* new(char* class, char* name) { Node* node = calloc(sizeof(Node), 1); SV* obj_ref = newSViv(0); SV* obj = newSVrv(obj_ref, class); node->name = strdup(name); sv_setiv(obj, (IV)node); SvREADONLY_on(obj); return obj_ref; } SV* set_name(SV* self, char* name) { ((Node*)SvIV(SvRV(self)))->name = strdup(name); SvREFCNT_inc(self); return self; } char* get_name(SV* self) { return ((Node*)SvIV(SvRV(self)))->name; } SV* set_parent(SV* self, SV* parent) { Node* me = (Node*)SvIV(SvRV(self)); SvREFCNT_inc(parent); if (me->parent) SvREFCNT_dec(me->parent); me->parent = parent; SvREFCNT_inc(self); return self; } SV* get_parent(SV* self) { SV* parent = ((Node*)SvIV(SvRV(self)))->parent; SvREFCNT_inc(parent); return parent; } void DESTROY(SV* self) { Node* node = (Node*)SvIV(SvRV(self)); fprintf(stderr, "Freeing %p (%s)\n", self, node->name); free(node->name); free(node); } }; #### SV* set_parent(SV* self, SV* parent) { Node* parent_node = (Node*)SvIV(SvRV(parent)); ((Node*)SvIV(SvRV(self)))->parent = parent_node; SvREFCNT_inc(self); return self; }