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/