Embedding perl
Upcoming SlideShare
Loading in...5
×
 

Embedding perl

on

  • 518 views

Bulgarian Perl Workshop 2011

Bulgarian Perl Workshop 2011

Statistics

Views

Total Views
518
Views on SlideShare
518
Embed Views
0

Actions

Likes
0
Downloads
1
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • Why would I want to do that? Get some performance by using native C for some of the processing Embed parts of your existing C application into your Perl app without rewriting it completely
  • XS is an interface description file format used to create an extension interface between Perl and C code extremely hard to learn even the smallest program must be implemented as additional module There is another, similar way using SWIG... I don't know how it works :( If someone is interested... www.swig.org
  • .
  • Scalar, Hash and Arrays are typedefs which can include any of the following types. You create the value with the coresponding newSV* function. You access the value with the coresponding Sv* function.
  • Describe the way we add and execute the C code.
  • Describe the way we add and execute the code. We begin the function with Inline_Stack_Vars This defines some internal variables including Inline_Stack_Items Inline_Stack_* variables can be used only when we use ... in the argument list or the return type of the function is VOID. sv_2mortal() – marks a variable as ready for destroy newSViv() - creates a Scalar Value from integer
  • We begin the function with Inline_Stack_Vars This defines some internal variables including Inline_Stack_Items Inline_Stack_* variables can be used only when we use ... in the argument list or the return type of the function is VOID. We have to have at least one argument before the variable length argument because of the XS parsing.
  • We begin the function with Inline_Stack_Vars This defines some internal variables including Inline_Stack_Items Inline_Stack_* variables can be used only when we use ... in the argument list or the return type of the function is VOID. We have to have at least one argument before the variable length argument because of the XS parsing.
  • Why would I want to do that? Use Perl's RE Package your software into a single binary Use some of the nice Perl already working perl modules in your C application
  • In all cases ExtUtils::Embed will help with the compilation flags. B::C is used for direct compile (perlcc) but is available only for perl 5.8.0 or 5.13.x. Using XS seams the only portable/compatible way...
  • it should work with perl >=5.10 but i haven't made it to work :(

Embedding perl Embedding perl Presentation Transcript

  • Embedding Perl in C and the other way around  Marian Marinov(mm@1h.com   Co-Founder and CIO of 1H Ltd.
  • Embedding C in Perl   
  • The XS way... It cannot be seen, cannot be felt, Cannot be heard, cannot be smelt. It lies behind stars and under hills, And empty holes it fills. - J.R.R. Tolkien, The Hobbit Answer: dark.   
  • XS Docs● perlman:perlxstut● man perlxs● man perlguts● man perlapi● man h2xs   
  • XS Basics● SV – Scalar Value SV* newSVsv(SV*);● AV – Array Value● HV – Hash Value● IV – Integer Value SV* newSViv(IV);● UV – Unsigned Integer Value SV* newSVuv(UV);● NV – Double Value SV* newSVnv(double);● PV – String Value●SV* newSVpv(const char*, STRLEN);●SV* newSVpvn(const char*, STRLEN);●SV* newSVpvf(const char*, ...); SvIV(SV*) SvUV(SV*) SvNV(SV*) SvPV(SV*, STRLEN len) SvPV_nolen(SV*)   
  • Inline::C$ cat inline.pl#!/usr/bin/perluse Inline C=>void some_func() { printf("Hello Worldn");};&some_func$ ./inline.plHello WorldExamples from Inline::C-Cookbook   
  • fun way of using Inline::C$ cat perl­sign.pl #!/usr/bin/perl use Inline C=>void C() { int m,u,e=0;float l,_,I; for(;1840­e;putchar((++e>907&&942>e?61­m:u)["n)moc.isc@rezneumb(rezneuM drahnreB"])) for(u=_=l=0;79­(m=e%80)&&I*l+_*_<6&&26­++u;_=2*l*_+e/80*.09­1,l=I) I=l*l­_*_­2+m/27.; };&C   
  • mmmmmmmmooooooooooooooooooooooooocccccccccc....is@zrre i.cccccccoooooooooommmmmmmmmmmoooooooooooooooooooooooccccccccccc.....iiscrr n@csi...ccccccoooooooooommmmmmmooooooooooooooooooooooccccccccccc....iiiss@n zMesii....cccccoooooooooommmooooooooooooooooooooocccccccccc....iisssssc@rn erccsiiiii..ccccooooooooomoooooooooooooooooocccccccc.......iis@e uMeu r e r@@@ezs..cccoooooooooooooooooooooooccccccc.........iiiisc@z e eci..cccoooooooooooooooooccccccc..iiiiiiiiiiiiisscz z z@sii.ccccoooooooooooccccccccc...iicz@ccccz@ccccccrrr s..cccooooooooocccccccc.....iisc@eb bnneree eci..ccccoooooocccccccc.....iisccrnb m nci..ccccoooooccc....iiiiisss@emee( cii..cccccooooiscc@@beremeene( Bernhard Muenzer(bmuenzer@csi.com) ercsi...cccccooooc....iiiiiisssc@e rnz esi...cccccoooooccccccc....iiiscc@rb ( esi..ccccooooooocccccccc......iisc@z bneze z@i..ccccoooooooooocccccccc....ii@er@@@@nr@cccc@e es..cccoooooooooooooooccccccc...@siiiiiiiiisssscnM urcsi..cccooooooooooooooooooooccccccc..........iiiisc@e zsi..cccooooooomooooooooooooooooocccccccc.......iiis@ nu er eznri.cccoooooooommoooooooooooooooooooocccccccccc....issc@ccc@@rn er@cssiiiss..cccooooooooommmmoooooooooooooooooooooccccccccccc....iiiisc@z rrsii.....ccccoooooooooommmmmmooooooooooooooooooooooocccccccccccc....iis@rz rrcsi....ccccccoooooooooommmmmmmmmmoooooooooooooooooooooooocccccccccc....iisceeeusi..cccccccooooooooommmmm    
  • Multiple Return Valuesprint map {"$_n"} get_localtime(time);use Inline C => <<END_OF_C_CODE;#include <time.h>void get_localtime(int utc) { struct tm *ltime = localtime(&utc); Inline_Stack_Vars; Inline_Stack_Reset; Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_year))); Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_mon))); Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_mday))); Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_hour))); Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_min))); Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_sec))); Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_isdst))); Inline_Stack_Done;}    END_OF_C_CODE
  • Variable Argument Listsgreet(qw(Sarathy Jan Sparky Murray Mike));use Inline C => <<END_OF_C_CODE;void greet(SV* name1, ...) { Inline_Stack_Vars; int i; for (i = 0; i < Inline_Stack_Items; i++) printf("Hello %s!n", SvPV(Inline_Stack_Item(i), PL_na)); Inline_Stack_Void;}END_OF_C_CODE    
  • Another way of using Inline::Cuse Inline C;$vp = string_scan($text); # call our function__END____C__/* * Our C code goes here */int string_scan(char* str) {}    
  • Embedding Perl in C   
  • How you can do it?● ExtUtils::Embed perl -MExtUtils::Embed -e ccopts -e ldopts● B::C● The only way... XS   
  • Docsman perlembedman perlcallman perlgutsman perlapiman perlxs   
  • B::C/perlcc● Works with Perl 5.6.0● Works with Perl 5.13.x#!/usr/bin/perluse strict;use warnings;use lib .;use parse_config;my $a = some text;my $b = 13;my %config = parse_config(/etc/guardian.conf);#my %config = ( df => 13, hj => 18);printf "%s %dn", $a, $b;while (my ($k,$v) = each %config) { print "$k :: $vn";}   
  • $ perlcc -o em em.pl$ ./emSegmentation fault$ perlcc -o em em.pl$ ./emsome text 13df :: 13hj :: 18   
  • #include "embed.h"int main (int argc, char **argv, char **env) { char *embedding[] = { "", "-e", "0" }; unsigned char *perlPlain; size_t len = 0; int err = 0; PERL_SYS_INIT3(&argc,&argv,&env); my_perl = perl_alloc(); perl_construct( my_perl ); perl_parse(my_perl, xs_init, 3, embedding, NULL); PL_exit_flags |= PERL_EXIT_DESTRUCT_END; perl_run(my_perl); perlPlain=spc_base64_decode(&perl64,&len,0,&err); eval_pv(perlPlain, TRUE); perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); return 0;   }
  • #ifndef _EMBED_H#define _EMBED_H#include <EXTERN.h>#include <perl.h>#include "base64.h"#include "code_64.h"static PerlInterpreter *my_perl;static void xs_init (pTHX);EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);EXTERN_C void boot_Socket (pTHX_ CV* cv);EXTERN_C void xs_init(pTHX) { char *file = __FILE__; /* DynaLoader is a special case */ newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader,file);}#endif   
  • $ ./embed --versionThis is perl, v5.10.1 (*) built for i386-linux-thread-multiCopyright 1987-2009, Larry WallPerl may be copied only under the terms of either the ArtisticLicense or theGNU General Public License, which may be found in the Perl 5source kit.Complete documentation for Perl, including FAQ lists, should befound onthis system using "man perl" or "perldoc perl". If you haveaccess to theInternet, point your browser at http://www.perl.org/, the PerlHome Page.   
  • # perl -MExtUtils::Embed -e ccopts -e ldopts-Wl,-E -Wl,-rpath,/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE -L/usr/local/lib /usr/lib/perl5/5.8.8/i386-linux-thread-multi/auto/DynaLoader/DynaLoader.a-L/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE -lperl-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc -D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe-Wdeclaration-after-statement -I/usr/local/include-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm-I/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE# gcc -o embed embed.c $(perl -MExtUtils::Embed -e ccopts -eldopts)   
  • call_argv("showtime", G_DISCARD | G_NOARGS, args); vs. eval_pv(perlPlain, TRUE); /** Treat $a as an integer **/ eval_pv("$a = 3; $a **= 2", TRUE); printf("a = %dn", SvIV(get_sv("a", 0))); /** Treat $a as a float **/ eval_pv("$a = 3.14; $a **= 2", TRUE); printf("a = %fn", SvNV(get_sv("a", 0))); /** Treat $a as a string **/ eval_pv("$a = rekcaH lreP rehtonA tsuJ; $a = reverse($a);",TRUE); printf("a = %sn", SvPV_nolen(get_sv("a", 0)));