----- Original Message ----- From: "Marvin Humphrey" <[EMAIL PROTECTED]> To: <inline@perl.org> Sent: Tuesday, June 21, 2005 11:08 AM Subject: Re: Object Oriented Inline C
> On Jun 20, 2005, at 5:36 PM, Sisyphus wrote: > > > Yes, I agree. I was surprised that the script in the cookbook > > produced that > > error (because the code looks correct to me) - and I don't know > > what the > > correct fix is. There's no problem with that cookbook script with > > perl 5.6. Should have realised what the problem was - Eric's post on this aspect draws attention to it. > > I'm concerned, because I'm integrating this very technique into a > CPAN distro (Search::Kinosearch) using Inline::C. Maybe I'll have to > go XS. :\ > I don't expect that would help. Eric's post reminded me that the good advice is to always use the perl api equivalents rather than 'malloc' (which presumably gets called by 'strdup') and 'free' - and if I rewrite the cookbook script in such a way that it adheres to that "good advice" (reproduced below), then there's no problem with it. Cheers, Rob my $obj1 = Soldier->new('Benjamin', 'Private', 11111); my $obj2 = Soldier->new('Sanders', 'Colonel', 22222); my $obj3 = Soldier->new('Matt', 'Sergeant', 33333); for my $obj ($obj1, $obj2, $obj3) { print ($obj->get_serial, ") ", $obj->get_name, " is a ", $obj->get_rank, "\n"); } package Soldier; use Inline C => <<'END'; typedef struct { char* name; char* rank; long serial; } Soldier; SV* new(char* class, char* name, char* rank, long serial) { Soldier* soldier; New(42, soldier, 1, Soldier); if(soldier == NULL) croak("Failed to allocate memory for 'soldier' in new function"); SV* obj_ref = newSViv(0); SV* obj = newSVrv(obj_ref, class); Newz(43, soldier->name, strlen(name) + 1, char); if(soldier->name == NULL) croak("Failed to allocate memory for 'name' in new function"); soldier->name = name; Newz(44, soldier->rank, strlen(rank) + 1, char); if(soldier->rank == NULL) croak("Failed to allocate memory for 'rank' in new function"); soldier->rank = rank; soldier->serial = serial; sv_setiv(obj, (IV)soldier); SvREADONLY_on(obj); return obj_ref; } char* get_name(SV* obj) { return ((Soldier*)SvIV(SvRV(obj)))->name; } char* get_rank(SV* obj) { return ((Soldier*)SvIV(SvRV(obj)))->rank; } long get_serial(SV* obj) { return ((Soldier*)SvIV(SvRV(obj)))->serial; } void DESTROY(SV* obj) { Soldier* soldier = (Soldier*)SvIV(SvRV(obj)); Safefree(soldier->name); Safefree(soldier->rank); Safefree(soldier); } END