Borse, Ganesh wrote:
Hi,
I am trying to create Perl subroutine in my C++ program, source code
> of which is given below -- attempt to embed Perl in C++ program.
I cannot use the perl script file for this because the expressions to
be evaluated are stored in database & are to be loaded at runtime.
This program compiles fine. Command line for that is also given.
But, program crashes when it calls perl_eval_pv function. When I ran it in GDB,
I got this back trace.
May I please know:
1) Is this correct way to create Perl subroutines in embedded Perl in C?
2) Why is this program is crashing when perl_eval_pv?
A) How to resolve this problem of crash?
-- should I link any more library or compile the Perl on my machine?
Please help.
Thanks in advance for help & guidance.
Regards,
Ganesh
Compilation command:
g++ -g3 -ggdb -Dbool=char -DHAS_BOOL
-I/usr/lib/perl5/5.8.0/i386-linux-thread-multi/CORE
-L/usr/lib/perl5/5.8.0/i386-linux-thread-multi/CORE -L/usr/lib -L. -lperl -lm
-lnsl -lgdbm -ldb -ldl -lpthread -lc -lcrypt -lutil testeval.cpp
rpm -qf /usr/bin/perl
perl-5.8.0-88.4
Program source code:
#include <EXTERN.h>
#include <perl.h>
static PerlInterpreter *my_perl;
main()
{
my_perl = perl_alloc();
perl_construct(my_perl);
char peExpr[] =\
"sub isSizeSmall($size,$vol,$ADV,$prod)\n"\
"{\n"\
" my ($size,$vol,$ADV,$prod) = @_;\n"\
" if ( ($size < 1000) && ($vol < (0.001 * $ADV)) && ($prod =~ m/Stock/)){\n"\
" return 10;\n"\
" } else {\n"\
" return 11;\n"\
" }\n"\
"}\n";
printf("expression: \n[%s]\n",peExpr);
// Parse this subroutine & add to interpreter
perl_eval_pv(peExpr,TRUE);
// now call this subroutine with 4 input arguments in an array
char *peArgs[] = { "100","1000","100000","\"Stock\""};
perl_call_argv("isSizeSmall",G_ARRAY,peArgs);
perl_destruct(my_perl);
perl_free(my_perl);
}
Gdb backtrace output when the program got SIGSEGV:
LD_LIBRARY_PATH=/usr/lib/perl5/5.8.0/i386-linux-thread-multi/CORE:$LD_LIBRARY_PATH
Using host libthread_db library "/lib/tls/libthread_db.so.1".
(gdb) run
Starting program: /home/gborse/prgs/bakup/perl/a.out
[Thread debugging using libthread_db enabled]
[New Thread -1223159680 (LWP 23628)]
expression:
[sub isSizeSmall($size,$vol,$ADV,$prod)
{
my ($size,$vol,$ADV,$prod) = @_;
if ( ($size < 1000) && ($vol < (0.001 * $ADV)) && ($prod =~ m/Stock/)){
return 10;
} else {
return 11;
}
}]
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1223159680 (LWP 23628)]
0xb757fa90 in S_doeval (my_perl=0x8049c48, gimme=0, startop=0x0) at
pp_ctl.c:2774
2774 pp_ctl.c: No such file or directory.
in pp_ctl.c
Current language: auto; currently c
(gdb) bt
#0 0xb757fa90 in S_doeval (my_perl=0x8049c48, gimme=0, startop=0x0) at
pp_ctl.c:2774
#1 0xb7581412 in Perl_pp_entereval (my_perl=0x8049c48) at pp_ctl.c:3353
#2 0xb74e678f in S_call_body (my_perl=0x8049c48, myop=0xbfffa370, is_eval=1)
at perl.c:2064
#3 0xb74e69d2 in Perl_eval_sv (my_perl=0x8049c48, sv=0x0, flags=0) at
perl.c:2129
#4 0xb74e6c1a in Perl_eval_pv (my_perl=0x8049c48, p=0x0, croak_on_error=1) at
perl.c:2188
#5 0x08048804 in main () at testeval.cpp:31
(gdb)
//-------------------------------------------------------------------------------------------------
Two things I can see wrong here. First of all you /must/ call perl_parse
to parse the command line before you can use the interpreter, even if
you have no command line. To do this just build a dummy command line
like this
PerlInterpreter *my_perl = perl_alloc();
perl_construct(my_perl);
char *dummy_argv[] = {"", "-e", "0"};
perl_parse(my_perl, NULL, 3, dummy_argv, NULL);
This corresponds to the invocation
perl -e 0
which does nothing useful but lets us go on to use the interpreter.
Secondly you need a null termination to the argument list for the call
to perl_call_argv. This is probably what's causing your seg fault. Write
it as
char *peArgs[] = {"100", "1000", "100000", "\"Stock\"", NULL};
and all should be well.
HTH,
Rob
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/