Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re: embedded perl: C-Perl-C

by wog (Curate)
on Sep 21, 2001 at 05:08 UTC ( [id://113760]=note: print w/replies, xml ) Need Help??


in reply to embedded perl: C-Perl-C

To allow your embedded code to have callbacks from perl, you can compile .xs file(s) having XS functions doing the desired tasks. Your C library would create the bootstrap function for your module (like done in the example xs_init function in perlembed) and call the bootstrap method for the XS module (a task ordinarily be done by a .pm file, which if may be a better place to put this if you provide real .pm files somehow). If you do not want to divide your code into perl embedding files and perl XS files, you can put most of your non-XS code at the top of the .xs file(s) before the MODULE = line.

You may find it helpful to look at the perl embeding portions of a program that embeds perl like this, for example, VIM (which I used to derive some of this information.)

Replies are listed 'Best First'.
Re: Re: embedded perl: C-Perl-C
by daveola (Sexton) on Sep 21, 2001 at 13:40 UTC
    If I'm not mistaken, then I can compile C code into perl that I can call from perl. But that doesn't quite solve my problem - because it won't allow me to call the C functions that started up the perl interpretor in the first place, will it? It just calls the C functions that were compiled into the perl library - right? Take a look at the example pseudo-code I want to be able to do - I want to call a function in the original C code that alters state inside that space.
      I was referring to setting up XS within perl embedded in C. This XS would handle your callbacks from perl. To give an example which should clarify things somewhat, here's an an xs file with perl embedding built-in:

      #include <stdio.h> #include "EXTERN.h" #include "perl.h" #include "XSUB.h" static PerlInterpreter* my_perl; static int my_c_var; static void xs_init(pTHX); extern void boot_DynaLoader(pTHX_ CV* cv); void boot_Example (pTHX_ CV* cv); static void xs_init(pTHX) { /* set us up for dynamicly loaded modules */ newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, __FILE__); /* setup our module included in this file */ newXS("Example::bootstrap", boot_Example, __FILE__); } static void init_our_modules() { static const char* bootstrap_args[] = { "Example", NULL }; /* equivilent to bootstrap Example; pretty much */ call_argv("Example::bootstrap", G_DISCARD, bootstrap_args); } /* main function. In a library you'd probably use a different callback and do this in multiple functions, but I think you can get the idea. */ int main(int argc, char** argv, char** env) { /* same fake args for perl_parse */ /* we turn on warnings by default here. 'cuz they're good. */ static const char* perl_argv[] = { "", "-w", "-e", "0" }; my_c_var = 1; my_perl = perl_alloc(); perl_construct(my_perl); /* just to initiaize it */ perl_parse(my_perl, xs_init, 4, perl_argv, NULL); /* run END blocks in perl_destruct */ PL_exit_flags |= PERL_EXIT_DESTRUCT_END; init_our_modules(); puts("Perl seems to be initialized.\n"); printf("my_c_var = %d\n", my_c_var); eval_pv( /* Hey, perl programs in C code! */ "use strict;\n" "$\\ = qq[\\n];\n" "print q[get_my_c_var() = ], Example::get_my_c_var();\n" "Example::set_my_c_var(42);\n" "print q[get_my_c_var() = ], Example::get_my_c_var();\n" , TRUE); printf("my_c_var = %d\n", my_c_var); perl_destruct(my_perl); perl_free(my_perl); } /* And some XS code. */ MODULE = Example PACKAGE = Example int get_my_c_var() CODE: RETVAL = my_c_var; OUTPUT: RETVAL void set_my_c_var(newval) int newval CODE: my_c_var = newval;

      On my system I can compile this by first generating a .c file with:

      perl `perl -MConfig -le 'print $Config{privlibexp}'`/ExtUtils/xsubpp - +prototypes -typemap `perl -MConfig -le 'print $Config{privlibexp}'`/E +xtUtils/typemap Example.xs > example.c

      (I copy this strategy from what vim appears, though it would probably be better to do this by going through the work of extracting it from a Makefile.PL created Makefile.)

      This I compiled it with:

      `perl -MConfig -e 'print $Config{cc}'` -o example example.c `perl -MEx +tUtils::Embed -e ccopts -e ldopts`

      (This, for some reason gave two warnings about incompatible pointer type casts, which didn't seem to cause a problem.)

      Running the resulting program reveals:

      Perl seems to be initialized. my_c_var = 1 get_my_c_var() = 1 get_my_c_var() = 42 my_c_var = 42

      Hope this can be of some help.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://113760]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (2)
As of 2024-04-19 18:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found