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