jpollack has asked for the wisdom of the Perl Monks concerning the following question:

Greetings programs,

I am attempting to write a complete perl interface to an existing library and SDK. The library is centered around processing of a data stream and is written in C; it has a few simple interface functions, and uses a user specified callback function to do all the work.

I've read (okay, somewhere btw. skimmed and read) perlcall, perlapi and perlguts. I've managed to write C code, and a special C wrapper for a user specified perl callback function. This part works. I can currently compile my C code, start it, and it will run the callback function which is written in perl. (every invocation of the C callback does a sv_setpvn, ..., call_pv, POPpx, memcpy, &c)

I've also written XS code to successfully let me access the other functions in the library (other than the register_callback function) successfully.

My question is this: What do I write in my XS code to let me ... run code in the calling interpreter's instance? When I try to call newSVpv in a c file being linked against my XS file I get errors about *my_perl not existing. Is there some XS function or keyword to get a pointer to the calling perl instance? My goal is to have a 'registercb' function in the XS file (which takes SV *name), and have the c-language callback function use call_sv (name ..).

Any help? Has anyone written a perl interface to a callback based library before that can offer advice?

Replies are listed 'Best First'.
Re: perl->c->perl
by creamygoodness (Curate) on Dec 12, 2005 at 17:55 UTC
    That error seems to appear when the C library doesn't #include one of the essential Perl header files. Try adding this to the top of the offending library.

    #include "EXTERN.h" #include "perl.h" #include "XSUB.h"

    It's one of those three, I'll wager.

    --
    Marvin Humphrey
    Rectangular Research ― http://www.rectangular.com
Re: perl->c->perl
by philcrow (Priest) on Dec 12, 2005 at 17:43 UTC
    This may seem completely unrelated, but what you are attempting would almost certainly be easier with Inline::C which handles all the details you are describing, but with a simple API.

    Phil

      I don't think that would be possible. As I understand, Inline::C is useful for calling C functions from perl, but how would you call a function that requires a function pointer as an argument? For instance, how would I write a callback function using Inline::C? The libraries register_callback routine needs a (*)(void *, void*, unsigned long, Timestamp, void *). What function pointer could I then pass it?

        Inline::C lets you write plain C functions too, and to callback from C to Perl you need a plain C function that calls one of the "call into Perl" subroutines. So callbacks from C to Perl are just as possible (and easier to write) with Inline::C instead of XS.

        The trick is getting at context. If you are lucky, then the callback interface allows you to have a context indicator passed to the callback. If not, then things get ratherr complicated...

        Unfortunately, I've run out of time for now...

        - tye        

      Inline::C is brilliant and useful and is not a substitute for XS, nor is it magical. It is a means of having a number of steps which used to be performed manually or semi-manually by the user, done automatically behind the scenes. My impression, having used Inline::C a bit, is that what the OP wants to do is something that requires real manual XS programming.

Re: perl->c->perl
by salva (Canon) on Dec 13, 2005 at 09:35 UTC
    post your code and we will try to see what you are doing wrong.