Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

embedding Perl into C for Windows

by ccad (Novice)
on Feb 11, 2014 at 17:40 UTC ( [id://1074459]=perlquestion: print w/replies, xml ) Need Help??

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

Hello PerlMonks, i want to embedd a perl interpreter into a C program. See below an example, very similar to the perl doc. Now the problem is: The C program and the perl sub are running fine under LINUX. Compiling under Windows7 works fine, too, but it crashes on start. What am i doing wrong? I used the latest Strawberry Perl und did the following: perl -MExtUtils::Embed -e ccopts -e ldopts > cp1.bat and modified this batch file by inserting gcc -o ccp2 ccp2.c (and the rest what was piped in). As i said, compiling under Windows was a breeze but on start the executable crashed.
/********************************************** * C calls a Perl subroutine and pushes two * double scalars.These two scalars are modified * in the sub and popped. * 7.2.2014 Frank **********************************************/ #include <EXTERN.h> #include <perl.h> #include <stdio.h> /*--------------------------------------------- * global variables *--------------------------------------------*/ double x, y; int icoun; static PerlInterpreter *my_perl; /*--------------------------------------------- * the C-"Assembly"routine *--------------------------------------------*/ static void harry(double x, double y) { printf("in Harry vor call, x= %lf, y= %lf\n",x,y); dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSVnv(x))); // PUSH one double "n" XPUSHs(sv_2mortal(newSVnv(y))); // PUSH one double "n" PUTBACK; icoun= call_pv("points",G_ARRAY); SPAGAIN; y= POPn; // POP one double "n" x= POPn; // POP one double "n" printf("in Harry after call, icoun= %d, x= %lf, y= %lf\n",icoun,x,y); PUTBACK; FREETMPS; LEAVE; } /*--------------------------------------------- * main *--------------------------------------------*/ int main(int argc, char **argv, char **env) { char *my_argv[]= {"", "punkte2.pl"}; x= 3.1416; y= 47.11; printf("Controll of the entry values\n"); printf("X= %lf, Y= %lf\n",x,y); /*============================================= * start Perl Interpreter *============================================*/ my_perl= perl_alloc(); perl_construct(my_perl); perl_parse(my_perl,NULL, 2, my_argv, (char **)NULL); perl_run(my_perl); /*============================================= * launch the C-"Assembly" routine *============================================*/ harry(x,y); /*============================================= * ...and clean up *============================================*/ perl_destruct(my_perl); perl_free(my_perl); } #********************************************* # the Subroutine points # 7.2.2014 Frank #********************************************* sub points { my ($xup,$yup)= @_; # value,value print "in der Subroutine\n"; # kleiner Test print "XUP= $xup, YUP= $yup\n"; $xup *= 3; $yup *= 4; return $xup, $yup; }
Has anyone an idea? Many thanks in advance! Frank

Replies are listed 'Best First'.
Re: embedding Perl into C for Windows
by syphilis (Archbishop) on Feb 11, 2014 at 23:55 UTC
    Hi,

    With the code you posted, I too get a crash on latest Strawberry Perl (5.18.2).
    By inserting a couple of debug printf() statements, I found that it crashed when perl_parse() was executed. Same for you ?

    However, there's a very similar example given in Strawberry Perl's perlembed (perldoc perlembed) documentation:
    #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; static void PerlPower(int a, int b) { dSP; /* initialize stack pointer */ ENTER; /* everything created after here */ SAVETMPS; /* ...is a temporary variable. */ PUSHMARK(SP); /* remember the stack pointer */ XPUSHs(sv_2mortal(newSViv(a))); /* push the base onto the stack */ XPUSHs(sv_2mortal(newSViv(b))); /* push the exponent onto stack */ PUTBACK; /* make local stack pointer global */ call_pv("expo", G_SCALAR); /* call the function */ SPAGAIN; /* refresh stack pointer */ /* pop the return value from stack */ printf ("%d to the %dth power is %d.\n", a, b, POPi); PUTBACK; FREETMPS; /* free that return value */ LEAVE; /* ...and the XPUSHed "mortal" args.*/ } 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(3, 4); /*** Compute 3 ** 4 ***/ perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }
    With the file "power.pl" that contains:
    sub expo { my ($a, $b) = @_; return $a ** $b; }
    That example works fine, for me.
    By working through the differences, you should be able to determine the reason(s) that one works, but the other doesn't.
    (I'm assuming the version provided by the Strawberry docs works for you.)

    Cheers,
    Rob
      Hello Rob, this was the missing link:
      PERL_SYS_INIT3(&argc,&argv,&env); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; PERL_SYS_TERM();
      I added these three commands - now it works! Many, many thanks - great! Greeting from Germany Frank
Re: embedding Perl into C for Windows
by Anonymous Monk on Feb 11, 2014 at 21:23 UTC
      Ditto on PERL_SYS_INIT3(&argc,&argv,&env);. It does nothing on no-threads Unix, but it mandatory on windows to setup process global (not interp/ithread global) data. Im not sure if it does something on ithreads unix.
        Hello bulk88, this was the missing link:
        PERL_SYS_INIT3(&argc,&argv,&env); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; PERL_SYS_TERM();
        I added these three commands - now it works! Many, many thanks - great! Greeting from Germany Frank
      Hello anonymous monk, thanks for your answer. The solution was:
      PERL_SYS_INIT3(&argc,&argv,&env); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; PERL_SYS_TERM();
      I added these three commands - now it works! Frank

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1074459]
Approved by karlgoethebier
Front-paged by ww
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (6)
As of 2024-03-19 10:09 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found