Hey Rob,

One approach would be to use a wrapper wrapper:

use Inline C => <<'EOC';
  void c_printf(char *format, AV * arguments) {
    ...
  }
EOC

sub wrap_printf {
  my $format = shift;
  c_printf($format, [EMAIL PROTECTED]);
}

wrap_printf("%d\n", $x);
wrap_printf("%#o\n", $y);



 -Ken

> -----Original Message-----
> From: Sisyphus [mailto:[EMAIL PROTECTED]
> Sent: Wednesday, August 18, 2004 10:42 PM
> To: inline
> Subject: Wrapping variable length agument lists
> 
> 
> 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