in reply to Re: Re: embedded perl: C-Perl-C
in thread embedded perl: C-Perl-C
#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.
|
|---|