1 / 16

PerlGuts->PerlEmbed->PerlCall

PerlGuts->PerlEmbed->PerlCall. Calling Perl from your C program. PerlGuts. SV – the basic variable AV – Array HV – Hash STASH – Package / Namespace. PerlGuts. PerlAPI. newSV, newSVpv, newSViv …. sv_setpv/iv/nv Sv(Flag): SvCUR, SvIOK, SvPOK …. SvIV, SvPV

nemo
Download Presentation

PerlGuts->PerlEmbed->PerlCall

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. PerlGuts->PerlEmbed->PerlCall Calling Perl from your C program

  2. PerlGuts SV – the basic variable AV – Array HV – Hash STASH – Package / Namespace

  3. PerlGuts

  4. PerlAPI newSV, newSVpv, newSViv …. sv_setpv/iv/nv Sv(Flag): SvCUR, SvIOK, SvPOK …. SvIV, SvPV SvREFCNT, SvREFCNT_inc, SvREFCNT_dec newAV, av_pop, av_unshift, av_fetch newHV, hv_store, hv_fetch Total: 400 API functions + tons of macros

  5. PerlGuts – other concepts • Mortal variables • sv_2mortal • Perl Stack • @_

  6. PerlEmbed A Simple Embedded Perl: #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(int argc, char **argv, char **env) { PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct(my_perl); perl_parse(my_perl, NULL, argc, argv, (char **)NULL); perl_run(my_perl); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); }

  7. #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(int argc, char **argv, char **env) { PERL_SYS_INIT3(&argc,&argv,&env); char *my_argv[] = { "", "power.pl" }; 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); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); } A Simple Embedded Perl:

  8. #include <EXTERN.h> #include <perl.h> static PerlInterpreter *my_perl; int main(int argc, char **argv, char **env) { PERL_SYS_INIT3(&argc,&argv,&env); char *embedding[] = { "", "-e", "0" }; my_perl = perl_alloc(); perl_construct(my_perl); perl_parse(my_perl, NULL, 3, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; eval_pv(“my $a=5; print $a x 3;”, FALSE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); } A Simple Embedded Perl:

  9. Conventions • d – define / declare • a – argument • p – parameter • _ - there should be a comma after Example: aTHX_

  10. #include <EXTERN.h> #include <perl.h> int main(int argc, char **argv, char **env) { PERL_SYS_INIT3(&argc,&argv,&env); char *embedding[] = { "", "power.pl" }; PerlInterpreter *perl_inter; perl_inter = perl_alloc(); perl_construct(perl_inter); dTHXa(perl_inter); perl_parse(perl_inter, NULL, 2, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; char *name = “MyPackage”; load_module(PERL_LOADMOD_NOIMPORT, newSVpvn(name, strlen(name)), Nullsv); call_func(aTHX_ 7, 5); perl_destruct(perl_inter); perl_free(perl_inter); PERL_SYS_TERM(); }

  11. If my function is: sub Multiply { print $_[0]*$_[1] } void call_func(pTHX_ int x, int y) { dSP; char *params[] = {“5”, “7”, NULL}; call_argv(“Multiply”, G_DISCARD, params); } Flags: G_VOID, G_SCALAR, G_ARRAY, G_DISCARD, G_NOARGS, G_EVAL, G_KEEPERR

  12. void call_func(pTHX_ int x, int y) { dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(x))); XPUSHs(sv_2mortal(newSViv(y))); PUTBACK; call_pv("Multiply", G_DISCARD); FREETMPS; LEAVE; } Now let’s add two more functions: sub Multiply2 { return $_[0]*$_[1] } sub some_calcs { return ($_[0]+$_[1], $_[0]-$[1]) }

  13. int call_func(pTHX_ int x, int y) { dSP; int count; int ret = -1; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(sv_2mortal(newSViv(x))); XPUSHs(sv_2mortal(newSViv(y))); PUTBACK; count = call_pv("Multiply2", G_SCALAR | G_EVAL); SPAGAIN; if (SvTRUE(ERRSV)) { // There was an error char *err_str = SvPVX(ERRSV); POPs; } else { ret = POPi; } FREETMPS; LEAVE; return ret; } Always, even if there was an exception, pop a value off the stack

  14. int call_func(pTHX_ int x, int y) { ... count = call_pv(“some_calcs", G_ARRAY | G_EVAL); SPAGAIN; // count – can be 0 (exception, empty list) // One way to access the returned values is with the // POPx macros – but will receive results in reverse // order. Other way: (should include xsub.h) I32 ax; SP -= count; ax = (SP - PL_stack_base) + 1; // And then: printf(“Added: %d, Substracted: %d\n”, SvIV(ST(0)), SvIV(ST(1))); ... }

  15. Dynamic Loader EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); EXTERN_C void xs_init(pTHX) { char *file = __FILE__; dXSUB_SYS; /* DynaLoader is a special case */ newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); } And then: perl_parse(perl_inter, xs_init, 3, my_argv, (char **)NULL);

  16. Sources Perldoc: perlhack, perlguts, perlembed, perlcall, perlapi PerlGuts Illustrated (http://gisle.aas.no/perl/illguts/)

More Related