in reply to SOLVED: XS: Passing an external library's function a Perl XS callback

What happens if you add
PUTBACK; FREETMPS; /* free that return value */ LEAVE; /* ...and the XPUSHed "mortal" args.*/

Replies are listed 'Best First'.
Re^2: XS: Passing an external library's function a Perl XS callback
by stevieb (Canon) on Aug 14, 2016 at 20:32 UTC

    Do you mean within callback()? I put those lines before and after the call to the actual perl sub, but both cases still result in segfault.

        I greatly appreciate the feedback to try, AnonyMonk!

        With the last code, static didn't work, so I removed that. I also initialized a and b. This very slightly modified declaration (yep, I corrected the def as well):

        void callback(){ int a = 10; int b = 20; dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(a))); XPUSHs(sv_2mortal(newSViv(b))); PUTBACK; call_pv("p_callback", G_DISCARD|G_NOARGS); SPAGAIN; printf("%d to the %dth power is %d.\n", a, b, POPi); PUTBACK; FREETMPS; LEAVE; }

        ...with the exact same otherwise all around, produces:

        in init in perl callback Use of uninitialized value in subroutine entry at c_extern_call_perl.p +l line 11. 10 to the 20th power is -474476032. Segmentation fault

        So, callback() is working perfectly on the direct call from the perl code, it still registers ok in the external function, but as soon as the callback is triggered from extern, it breaks, from my estimation, at or before the call to call_pv().

        Update: I moved around some comments, and it segfaults on anything following the call to dSP().

        Perhaps I'm XY Problem-ing this. Here's what I want...

        • extern C function requires a void func(void) function pointer as a callback
        • I would really prefer not to modify the external code, if I can avoid it (I'd really like it to be void func(const char *string) realistically, I think, but I am a C newb)
        • to avoid the void/void, on the perl side, I want a user to send in a cref to a Perl method, which calls an XSUB to send in a pre-defined XSUB callback that points to the cref to the external C function (this all works)
        • when an event is triggered, and the already-registered callback in the extern is called, it should call the user-supplied cref in the main module's (in the case I've exampled here, the main script) perl code

        Am I making sense here? Perhaps I'm thinking this totally wrong. I'm going to keep pounding on this because I know there's got to be a way :) I'm just not experienced enough in all of the cross-language comms, and using XS. I'm having fun though