Last week, I have been writing my first perl extension. I wanted to conclude my experiences with a description of the hickups, because I was a little surprised by how little nodes here actually provide some help with XS. This really is a request for a tutorial on how to pass arguments to/from XS.

Start off

Actually, the start was pretty straightforward. I printed perlxs, perlxstut, and perlguts, and took off. I followed perlxstut, and with h2xs I promptly obtained a framework to start with.

First lines of code

I copy/pasted the single C-function I wanted to implement (a smoother) into the CODE block, made up some name, and than I landed at the first quirk: the code needed some C-macro, and I had no clue from the docs where to put it. I glanced through the files found by 'locate .xs', and quickly saw you just can put them before the function declaration. Did so, and it worked.

Float *?

Than I came at the point I wanted to pass my arguments. I had some arrays, some ints and some floats, and the C-code used floats. I first started with the ints, no problem, and than the floats. OK, than the array with float *, as in the C-function declaration. Here came the first errors from gcc: the XS interface did not recognize float *. I read up in the tut: It mentioned to use a typemap. An example was to be found in the perl source. Indeed, somewhere buried in the ext/ tree I found some typemaps, and I hit one with a float * line. Well, that didn't work at all. Again, I browsed through all the .xs on my box, but didn't find any that actually interfaced with a float *.

Arrays

Than I stumbled across the perlguts (I had printed it for some reason!), and it mentioned ways to implement perl-arrays in C. Well, I tried AV * and variations on the theme without getting any sensible array-item across. A perlmonks search did wonders: I found a reply by tye, and he basically said to pack your array, and interface it by char *, and typecast it with (double *). This worked like a charm, I had my variables in C. The original code used an array type rather than a pointer, so I had to convert it into a c-array in a loop. Lots of conversions, but it worked. In the module, I implemented the pack/unpack conversions, so all became transparant for the end-user (me ;).

Output arrays

Of course I thought, for the output I take a pointer to my array, than cast that back to a char *, and there I am. No way! Whatever variation on this, I got the value of the pointer back at most. So I had to come up with something else, and I finally got meself some succes by declaring a perl-scalar. It goes like:
SV * array_out; //the code array_out = newSVpv( (char *) z, m * 8 ); RETVAL = array_out; OUTPUT RETVAL
SV is the internal name for a scalar (AV for array; HV for hash, see perlguts). NewSVpv assigns some string to that scalar. When passing a string without \000 termination (aka 'pascal string'), you need to tell how much bytes you wanna have, here the number of items times the sizeof(double). Put out like this, it works like a charm. Crunches some 100 times faster than the routine I used in matlab, and it can be called from within perl.

Tutorial?

All together, I think I would have liked some elaboration in a tutorial on howto pass arguments between C and perl. For example, ints go without a problem, but the arrays are a horror, and I didn't even touch arrays of strings or even hashes. I would be delighted if someone has written/ would like to write a tutorial on the subject, to help stumbling starters like myself.

Jeroen
"We are not alone"(FZ)


In reply to First contact with XS passing arrays, or: Request for a tutorial by jeroenes

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



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.