Hi,
Suppose I wanted to write a wrapper for the C printf() function - something like:
use warnings; use Inline C => <<'EOC';
void wrap_printf(SV * a, SV * b) { if(SvUOK(b)) printf(SvPV_nolen(a), SvUV(b)); if(SvIOK(b)) printf(SvPV_nolen(a), SvIV(b)); if(SvNOK(b)) printf(SvPV_nolen(a), SvNV(b)); }
EOC
$x = -32; $y = 40;
wrap_printf("%d\n", $x); wrap_printf("%#o\n", $y);
That would work fine (up to a point) - but, of course, instead of writing the wrap_printf() function twice, I would want to do it as one function call, just as you would with the printf() function:
wrap_printf("%d\n%#o\n", $x, $y);
That, of course, no longer works. The wrap_printf() function needs to be able to accommodate argument lists of varying lengths - so I thought:
void wrap_printf(SV * a, ...) { /* Code to transfer the supplied arguments to C's printf() function */ }
The only trouble now is that I don't know what that "Code" looks like and whether that "Code" can be written in a way that performs efficiently.
So now I'm thinking that wrap_printf() needs to take a reference to an array as its argument:
void wrap_printf(AV * arguments) { /* Code to transfer the referred arguments to C's printf() function */ }
I don't know, off the top of my head, exactly what *that* "Code" looks like either - though I'm confident I can work it out.
A slight problem with this last rendition is that one will now have to call wrap_printf() from perl as:
wrap_printf(["%d\n%#o\n", $x, $y]);
which is different to the usual printf() argument format - which would be unfortunate, though tolerable.
Any thoughts on what is the *correct* approach would be appreciated.
(The correct approach is to use perl's printf() function - but let's suppose, for the sake of argument, that perl doesn't have one. I guess that there's also some code somewhere in the perl source that would go a long way towards showing me the best way to go about it, but I'm a bit overwhelmed when it comes to actually locating that source code.)
Cheers, Rob