<[EMAIL PROTECTED]> writes: >I'm trying to write a C program that uses an embedded perl interpeter >to handle multiple AI scripts written in perl. The AI scripts need to >have distinct namespaces. Since most versions of Perl are not compiled >-DMULTIPLICITY and multiple interpreters consume a lot of resources, >I'm trying to do this with one perl interpreter rather than simply loading >handling each script with its own perl interpreter and dodging the >namespace issue that way. > >The problem I have is that I can't figure out how to expand the embedded >perl examples from perlembed to handle multiple script files. When I try >to perl_parse TWO files I always get an error trying to call a >subroutine in the second file--claiming "Undefined subroutine >&package::subroutine called" > >Here's the C program that handles ONE script file and the perl script it >calls. How do I get it to handle additional script files, that, for >argument's sake, >look exactly like the one I've got except for a different package name? >I know I shouldn't call perl_parse more than once (although it "works", >producing the error mentioned above).
perl_parse() is like "the" script passed to perl. It clears the symbol table... >I've tried putting both script names in >the my_argv array and upping argc to 3, which also compiles and runs >but can't find subroutines in the second file parsed. That is like saying perl BotAI1.pl BotAI2.pl 1st one is script ($0) , second one is $ARGV[0] So what you want is the embed equivalent of perl -e 'do $_ foreach @ARGV' BotAI1.pl BotAI2.pl i.e. a command line "script" (the -e) which loads all the other args. So somthing like this: char *my_argv[] = { argv[0], "-e", "do $_ foreach @ARGV", "BotAI1.pl", "BotAI2.pl", NULL }; perl_parse(my_perl, NULL, 5, my_argv, (char **)NULL); Should load all your Bots. The other alternative is to do Nothing as the script: char *my_argv[] = { argv[0], "-e", "", NULL }; perl_parse(my_perl, NULL, 3, my_argv, (char **)NULL); And then load each file using under-documented load_module() call. or a eval_pv("do BotAI1.pl",G_VOID) > >thanks > David > > >#include <EXTERN.h> >#include <perl.h> >#include <stdio.h> >#include <stdlib.h> >#include <string.h> > >char playerinfo[256]; >char visioninfo[256]; >char ai_command[256]; > >static PerlInterpreter *my_perl; > > static void CallAI(char * subname, char * a, char * b) > { > char * c; > > dSP; /* initialize stack pointer */ > ENTER; /* everything created after here */ > SAVETMPS; /* ...is a temporary variable. */ > PUSHMARK(SP); /* remember the stack pointer */ > XPUSHs(sv_2mortal(newSVpv(a,0))); /* push the base onto the stack */ > XPUSHs(sv_2mortal(newSVpv(b,0))); /* push the exponent onto stack */ > PUTBACK; /* make local stack pointer global */ > call_pv(subname, G_SCALAR); /* call the function */ > SPAGAIN; /* refresh stack pointer */ > c = POPp; /* pop the return value from > the stack, as a pointer */ > strcpy (ai_command, c); /* transfer this string to a globally scoped > variable... */ > PUTBACK; > FREETMPS; /* free that return value */ > LEAVE; /* ...and the XPUSHed "mortal" args.*/ > } > > int main (int argc, char **argv, char **env) > { > char *my_argv[] = { "", "BotAI.pl" }; > char ai_1_name[256]; > int argc = 2; > strcpy (ai_1_name, "bot1::get_ai_action"); > > my_perl = perl_alloc(); > perl_construct( my_perl ); > perl_parse(my_perl, NULL, argc, my_argv, (char **)NULL); > perl_run(my_perl); > sprintf (playerinfo, "%s", "This is playerinfo"); > sprintf (visioninfo, "%s", "Tree:Frog:Lemming"); > CallAI(ai_1_name, playerinfo, visioninfo); /* call function that > calls perl subroutine */ > //at this point ai_command has been set by the script > perl_destruct(my_perl); > perl_free(my_perl); > } > > > >and here is the perl script "BotAI.pl" it calls: > > >package bot1; > >sub get_ai_action >{ > my $playerinfo = shift; > my $visioninfo = shift; > my $ai_command = ""; > @seethings = split (/:/, $visioninfo); > $num_things = @seethings; > $ai_command = "I see $num_things things: "; > for ($i=0;$i<$num_things;$i++) > { > $ai_command = $ai_command."$seethings[$i] "; > } > return $ai_command; >}