Nick Ing-Simmons wrote:

> You pass sp in the example call but don't expect it the example func.
> Whether it is sane may depend on which you do!

Typo - it should be the first param to the function.  I don't appear to
reference it in the pushret_mystack routine either, but the macro SP and
the PUSHs do.  I didn't think that this was a particularly sane thing to
do, but it did work...

> The dire warnings are not just related to perl code - anything which grows
> the stack is a possible snag. Thus your EXTEND(SP,3) may cause stack to move,
> and indeed PUSHs's very reason for existance is to change the SP.
> and hence XSRETURN* to do funny things to the _old_ stack.
> I suggest you look at definitions of XSRETURN*
> One key to understanding this stuff is that an xsub returns "void",
> and XSRETURN* just diddles with variables - so there is no reason
> why the called sub cannot do the diddling:

Right - that makes sense.

> void
> pushret_mystruct(const struct mystruct *myst)
> {
>         dSP;
>         EXTEND(SP, 3);
>         PUSHs(sv_2mortal(newSVpv(myst->fielda, 0)));
>         PUSHs(sv_2mortal(newSViv(myst->fieldb)));
>         PUSHs(sv_2mortal(newSVpv(myst->fieldc, 0)));
>         PUTBACK;  /* copy SP to PL_stack_sp which XSRETURN uses */
>         XSRETURN(3);
> }

Ahah!  That makes sense, and it is so blindingly obvious once you see it
written down.

> ....
>         if (mystp = getmystructbyid(id)) {
>                 pushret_mystruct(mystp);
>                 return;
>         } else {
>                 XSRETURN_EMPTY;
>         }

Ditto here too.  I assume that if I wanted to refer to SP after the call
to pushret_mystruct I would have to call SPAGAIN to refresh the outer
routines version of SP - correct?

Thanks Nick,

Alan Burlison

Reply via email to