Thelonius has asked for the wisdom of the Perl Monks concerning the following question:

I'm fairly new to writing XS routines. I'm wrapping a routine
HPERRMSG(displaycode,depth,errorproc,errornum, buffer,buflength,status);
Where all parameters except the first are optional. Among other things, the routine can format an error message (passed in as errornum) into a text message in buffer.

So, what I coded after several tries is:

void hperrmsg(displaycode,...) int displaycode PROTOTYPE: $;@ PREINIT: int depth=0; int errornum=0; SV *buffer=NULL; char *pbuf; short buflength=0; int status=0; int parm_ct; CODE: /* ... other items omitted for clarity */ if (items > 4) { buffer = ST(4); } if (buffer == NULL || SvREADONLY(buffer)) { pbuf = NULL; } else { int tmplen=buflength+1; if (!SvPOK(buffer)) { SvPV_force(buffer, tmplen); } else { SvGROW(buffer+1, tmplen); } pbuf = SvPVX(buffer); } HPERRMSG(parm_ct, displaycode, depth, 0, errornum, pbuf, &buflength, &status); if (buflength) { pbuf[buflength] = '\0'; SvPOK_on(buffer); SvCUR_set(buffer, buflength); }
This works, but is it the right thing to do? I put in the check for SvREADONLY thinking the user might put in "undef" as a placeholder.

Any feedback?

Replies are listed 'Best First'.
Re: XS help
by MZSanford (Curate) on Oct 17, 2001 at 12:40 UTC
    I have written very few (2) XS modules for wrapping other code, and a few XS modules for companies from scratch ... making me less than an authority on XS, but from what i see here, this code should work very well.

    I would assume that <code lang="C">HPERRMSG()</code> allows for a NULL pbuf, but not knowing the function, depending on what this is, you may want to return if it is NULL ... but since i don't know <code lang="C">HPERRMSG()</code>, i am possibly very wrong.

    Last thing, and this is just me, i would suggest returning a status of some sort. Something as simple as 1 on success and <code lang="C">PL_undef</code> for failure. That way, even if <code lang="C">HPERRMSG()</code> returns void, you can return in the event of bad arguments (non-numeric, etc)

    my $cents = 2;