- Steve
-------- Original Message -------- Subject: Returning a list from an XSUB Date: Mon, 08 Sep 2003 15:05:20 +0100 From: Steve Hay <[EMAIL PROTECTED]> To: [EMAIL PROTECTED]
Hi,
I have an XSUB that calls a C function to get three integers, and then returns them (in list context). In scalar context it just returns a Boolean to indicate whether the C function succeeded or not. It currently looks like this:
void
my_func()
PREINIT:
I32 gimme;
int one, two, three; PPCODE:
gimme = GIMME_V;
if (My_Func(&one, &two, &three) == 0) {
if (gimme == G_SCALAR) {
XSRETURN_YES;
}
else if (gimme == G_ARRAY) {
EXTEND(SP, 3);
PUSHs(sv_2mortal(newSViv(one)));
PUSHs(sv_2mortal(newSViv(two)));
PUSHs(sv_2mortal(newSViv(three)));
}
}
else {
if (gimme == G_SCALAR)
XSRETURN_NO;
else if (gimme == G_ARRAY)
XSRETURN_EMPTY;
}I have a few questions about this:
- Am I correct in just ignoring the G_VOID case, or would it be better to return somehow immediately rather than waste time calling the C function (given that the C function has no side effects beyond setting the three integers)?
- Is the EXTEND(SP, 3) call correct for the 3 subsequent PUSHs() calls? I thought it was OK to call PUSHs() once without needing to call EXTEND(SP, 1), so perhaps I should only call EXTEND(SP, 2) when I have 3 values to return?
- Do I need the "else" case of the main "if" block at all? Presumably just falling off the end of the XSUB when the C function failed would achieve the same thing? Or is it better style to code it explicitly as above?
- Are the XSRETURN_* macros OK in a PPCODE section? The Perl manpages seem to say it's OK, but I read something somewhere (can't remember where) that it wasn't a good idea because the C code generated contains "return" statements in a void() subroutine.
Thanks in advance, - Steve
.
