Stanley Hopcroft <[EMAIL PROTECTED]> writes:
>Dear Ladies and Gentlemen,
>
>I am writing to ask some advice about returning a variable number of
>results from an XS in which the callled C function has a (callback)
>function pointer argument that it calls to produce the results.
>
>The situation is this,
>
>/* callback */
>
>void server_fn(struct print_job_info *p) {
>
>  printf()             /* I would like this to replaced by 
>                           pushing the formatted string onto the Perl 
>                          stack.
>
>                       eg XPUSHs(sv_2mortal(newSVpvf()))
>
>                       */
>}
>
>/* This is the function wrapped by the XS */
>
>int cli_print_queue(struct cli_state *cli, 
>                    void (*fn)(struct print_job_info *))
>
>It seems to me that 
>
>1 I can only return results to Perl by an explicit XSRETURN(items) after 
>the XPUSHs. 

Yes.

>
>Therefore I have to accumulate the number of XPUSHs in a global variable 
>updated by the C callback (server_fn() above)).
>
>Is that correct ?

But it already is - the perl stack pointer that is incremented by XPUSH().
Also what is the 'int' that function returns? Is that any help? 

>
>2 Otherwise, the C callback should either 
>
>2.1 update a global C structure that will then be accessed by the 
>calling XS (cli_print_queue)
>
>2.2 update a global Perl structure (eg an AV *) that will be returned by 
>the calling XS
>
>What is 'the recommended way' or what are some of the less obvious 
>tradeoffs in each of these ways ?

/* In the C part before the MODULE line */
void 
server_fn(struct print_job_info *p) 
{
 dSP;
 XPUSHs(sv_2mortal(newSVpvf()))
 PUTBACK;
}

...

/* Now the XS part */
MODULE ....
void
cli_print_queue(struct cli_state *cli)
PPCODE:
 {
  SV **start = SP;
  int ret;
  PUTBACK;  /* so global variable is up-to-date */
  ret = cli_print_queue(cli,server_fn);
  SPAGAIN;  /* Get SP after the XPUSHs */
  /* Do whatever is necessary for return value in 'ret' */
  XSRETURN(SP-start); /* Count of number pushed */
 } 

-- 
Nick Ing-Simmons
http://www.ni-s.u-net.com/

Reply via email to