Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
Hi,
In perldoc Inline::C-Cookbook you'll find an "Object Oriented Inline" example. The following script (which works fine) is based on that example. I think the only changes I've made is to replace the strdup() calls (which are buggy) with savepv() calls - and I've added a Devel::Peek::Dump() call to reveal the innards of the objects being returned. Oh, yes ... and I've replaced malloc/free with New/Safefree:
use Devel::Peek; 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"); } Dump($obj1); print "\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); SV* obj_ref = newSViv(0); SV* obj = newSVrv(obj_ref, class); soldier->name = savepv(name); soldier->rank = savepv(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 __END__ Outputs: 11111) Benjamin is a Private 22222) Sanders is a Colonel 33333) Matt is a Sergeant SV = PVIV(0x2f5b8c) at 0x2f4940 REFCNT = 1 FLAGS = (PADBUSY,PADMY,ROK) IV = 0 RV = 0x2f3ca4 SV = PVMG(0x2febbc) at 0x2f3ca4 REFCNT = 1 FLAGS = (OBJECT,IOK,READONLY,pIOK) IV = 3143860 NV = 0 PV = 0 STASH = 0x45fca8 "Soldier" PV = 0x2f3ca4 "" CUR = 0 LEN = 0
Some time ago, Ken Williams suggested a more succinct rewrite of the new() function. (See http://www.mail-archive.com/inline@perl.org/msg01370.html for the post to which I refer.) In light of Ken's post I changed the new() function to this:
SV* new(char* class, char* name, char* rank, long serial) { Soldier* soldier; New(42, soldier, 1, Soldier); soldier->name = savepv(name); soldier->rank = savepv(rank); soldier->serial = serial; return sv_setref_pv(newSViv(0), class, (void *)soldier); }
That change, however, has a small effect on the output of the above script. Instead of getting FLAGS = (OBJECT,IOK,READONLY,pIOK) as per the above Devel::Peek::Dump(), I now get FLAGS = (OBJECT,IOK,pIOK). The READONLY flag that the original version of the script explicitly turned on is missing.

Two questions:
1) Does/could it matter that the READONLY flag is missing ?
2) How do I re-instate that READONLY flag in the modified (more succinct) version of the new() function ?

I'm inclined to think that the answer to 2) is probably straightforward and that my attempts to find the answer have simply been plagued by my own idiocy. I tried the following rendition of new() but it, too, failed to turn on any readonly flags (according to Devel::Peek::Dump, anyway):
SV* new(char* class, char* name, char* rank, long serial) { Soldier* soldier; SV *ret, *temp = newSViv(0); New(42, soldier, 1, Soldier); soldier->name = savepv(name); soldier->rank = savepv(rank); soldier->serial = serial; ret = sv_setref_pv(temp, class, (void *)soldier); SvREADONLY_on(temp); SvREADONLY_on(ret); return ret; }
FWIW, I've long been using the technique that appears in the Inline::C Cookbook ... and I'm starting to wonder whether I ought to switch to using Ken's suggested succinctification.

Update: Part of the attraction of Ken's rewrite is that it seems to lend itself more readily to typemapping (as regards the OUTPUT section of the typemap). But I'm unsure about that, too :-)

Cheers,
Rob

In reply to Inline::C-Cookbook's "Object Oriented Inline" by syphilis

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2022-11-28 17:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?