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

hello,

i got a c++ project with a function called foo()

i got a perl script i embed from that c++ script

is it possible (and if how) to call the foo() function located in the calling c++ code from within the embedded perl code (while the c++ script ofc is running ... i dont look for some simple perlXS module stuff to load "dead" code)?

if anyone cares to write a very basic example that would be awesome becaus that thing is hardly documented if at all :-(

the hole story is: i am injecting a c++ dll into a game to have some fun and i want perl to play the AI part (controlling my units) ... so perl gets some info about the game state, does some WICKED(tm) computing and calls the appropriate funcs() from the c++ script (which is still running ofc) which are then hooks into the actual game ...

Replies are listed 'Best First'.
Re: perl c++ perlembed question
by Marshall (Canon) on Jun 27, 2009 at 03:43 UTC
    Is it possible to open a Pipe between 2 process'es and use than rather than perlXs?
    Update: yes it is possible to call Perl from C and vice-versa, but I think that a language indepent pipe protocol between processes is something to consider.
Re: perl c++ perlembed question
by ig (Vicar) on Jun 27, 2009 at 05:53 UTC
      how would inline::cpp help me with embedding perl in an c++ project AND THEN calling some functions that where declared BY THE SAME c++ CODE THAT embedded the perl script from WITHIN the running and embedded perl code?
        It doesn't matter which code embeds what. The only real difference between embedding perl in C and C in perl is that if you embed C code in perl you can use the standard perl interpreter to start everything, and otherwise you'll have to "manually" start the perl interpreter using a (short) bootstrap sequence in C.

        Once you've done that, you can call into C and C++ functions from perl and vice versa regardless of how the startup procedure was executed.

        You can look at the code produced by Inline::CPP to see how it calls CPP routines and how it compiles and links the code. In short, it is a way for you to generate your own examples that call your own code. But I agree that it will not produce an example of a C++ routine calling an embeded perl interpreter calling a C++ routine - sorry...

Re: perl c++ perlembed question
by Anonymous Monk on Jun 27, 2009 at 03:51 UTC
      thank you for your answer but that does not explain how to call a function from perl that is defined in the c++ code that embedded the perl code ... i only found "How to export functions from C++ to embedded perl. Options" http://groups.google.com/group/perl.xs/browse_thread/thread/190893fecc6bdc52
        I'm not exactly sure of your requirements - you would be better off to provide some simple/minimalist test program that demonstrates what you're attempting to achieve. (Since you have not yet worked out how to achieve what you're after, that test script would presumably not work - but if it gave us some hints regarding the essence of your aims, that might help.)

        Here's a basic, contrived example of how the return values of C functions (namely, the foo() and bar() functions) could be fed into the embedded perl process. It's just a slight modification of the 'power.c' example from perlembed:
        #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; static void PerlPower(int a, int b) { dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(a))); XPUSHs(sv_2mortal(newSViv(b))); PUTBACK; call_pv("expo", G_SCALAR); SPAGAIN; printf ("%d to the %dth power is %d.\n", a, b, POPi); PUTBACK; FREETMPS; LEAVE; } int foo(void) { unsigned long t = (unsigned)time( NULL ); return (t % 5) + 3; } int bar(void) { unsigned long t = (unsigned)time( NULL ); return (t % 4) + 2; } int main (int argc, char **argv, char **env) { char *my_argv[] = { "", "power.pl" }; PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct( my_perl ); perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl); PerlPower(foo(), bar()); /* foo() ** bar() */ perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }
        For that program to work, 'power.pl' needs to be also in the cwd - and needs to contain the following:
        sub expo { my ($a, $b) = @_; return $a ** $b; }
        Cheers,
        Rob
        thank you for your answer but that does not explain how to call a function from perl that is defined in the c++ code

        I thought it did. You use Win32::API (or C::DynaLib) from perl to load/call c functions

        or you write your own c++ dispatcher function, and you make it available to perl through xs/Inline::C/pickle.

Re: perl c++ perlembed question
by Zen (Deacon) on Jun 29, 2009 at 13:11 UTC
    Typing LIKE THIS when YOU WANT TO MAKE a POINT...

    ..is clearly not working. I'd suggest writing intelligent dispatchers on both sides.