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







Reply via email to