SlideShare a Scribd company logo
Perl XS By  John Scoles The Pythian Group Black Art? Your Handy  Friend ? Misunderstood  Brain Sucking Zombie from Hell?
My XS Story! The funny thing is the Chinese use the same word for  catastrophe  as they use for  opportunity
In The Beginning 1800+ line Makefile.PL 1000+ lines of XS  800+ lines of Perl 5300+ lines of pure 'C'
My 'C'  Background I  can  Spell 'c' correctly 87.654% of the time 18 times out of 20.
My XS Background at the time Well I know of them! Bart Simpson said it best when asked if he knew long division or multiplication
A Complete  FNG NEWBIE RETARD Whatever
So as Johny Cash would say I Fell into a  Burning  Ring of Fire
But? I Survived
So I went Looking for Answers What  there was, wasn't much However I did learn 10 different ways to say “Hello World”  What  there was, didn't help much What  there was, and still is, was dated What  there was,  usually  ended with  “ Read  Perl Guts”
Why Is This? This sums up the nature of XS programming There are 10 ways to do the same thing! None of them are 100% wrong  None of them are 100% right
Lets go back to the start We all know that Perl is written in  'C' Big Deal most languages are  written  in 'C' Most 'C' stuff will be familiar to a 'Perl' programmer  Perl is very cozy with 'C'
A Few Things to know about 'C' Can't do shit without a 'lib'  “I stand on the shoulders of giants!”  NANOS GIGANTIUM HUMERIS INSIDENTES Compiled Strictly Typed No Memory Management Function params are by value only
A Few Things to say about Perl Interpreted Loosely  Typed Managed Memory  Function params are by 'Ref' only Perl is Just 'C'  without  types
Stop, Look, Listen! What is it we are trying to do? Credits to Navy Beans it is already on CPAN Access an API Improve  performance  of Perl Link into a static Lib
How about DBI and DBD::Oracle Access an API (OCI) for DBD::Oracle for sure  'C' for DBI to make it speedy for one 26 lines of code to do a fetch Way back in the dark days there was a  direct link to OCI but it has died  Now with Dynamic Linking no need for static perl
Part the Second  'C' and 'Perl' in Detail Libs Memory Data
Data in 'C'  “ Those that go down to the 'C' in Structs” Defined Types (U32, oratext) Arrays  of types (int[], char[]) Primitive  types  (int char etc) Structs (named collection of types)
Struc  struc say_hi_in { char*  english; char* french; int*  binary; } Must be  declared  at compile time It takes up a block of memory  So an  unitialized  struc  takes up the same space as an  initialized  one NOT A HASH!!!
Memory  in 'C' “ If it is the  Captain's  mess? Let him clean it up!” We have to do it. malloc free 'C' is dumb must know what type it is pointing to  Pointers and such  *,& and ** * a pointer to something & the value the Pointer is  pointing  to  ** a pointer to a pointer char * name;
Libs in 'C' Points to an Object file .obj, .o, .so, .dll or  even  an exe That can be shared A .h or 'header file' is not  necessarily  code it is just a promise of code needed at compile time. Usually just a prototype of the function or struct.
Data in Perl Metadata struc sv { void* sv_any; U32  sv_refcnt; U32  sv_flags; } or  Perl knows about itself. This is ' undef ' in Perl!!!!
Our first look of the “Guts” of Perl  struc sv { void* sv_any; U32  sv_refcnt; U32  sv_flags; } sv_any  Is a  pointer  to any other of the 'Perl' strucs sv_refcnt   A count of  the  number of times this struc has been  referenced sv_flags Holds the metadata of a 'Perl' variable.  It utilizes bit logic  (bitmask)
Memory in 'PERL' II When an object is  referenced  it is  Incremented  by one  sv_refcnt  When an object  goes out of scope it is decremented   by one (most times) (most times) When it reaches 0 it is  garbage  collected by Perl  And the memory is freed
Libs in 'Perl' A .pm  file is  code t hat can be shared .
How 'C' and 'Perl' Work 'C' Source  -> Compiler  -> Machine  Code 'Perl' Sour c e  -> Interpreter  -> Syntax Tree -> Interpreter  -> Machine   Code Syntax Tree->  {opcodes} = struc{} struc{} ->xsub pointer If this just happens to point to a 'C' function It will run
Finally down to Brass Tacks Thank you good by:) X External S Subroutines eXternal Subroutines or XS
Now Some Code Far be it form me to break with  tradition   #Include <stdio.h> void print_hi_larry(void) { printf(“Hello Larry!”);  } Int main(int argc,char *argv[]){ print_hi_larry(); exit(0); } So to the left is  hello  Larry in 'C'
How about a Perl File for it lib/Hi_ larry.pm Hi_ larry.xs Makefile.PL README t/test.t Changes MANIFEST Like most things in perl we have a Helper called  h2sx In our case we do H2sx -A -n Hi_ larry And it  generates  all of our perl files thank you very much
So all we do is open the .xs file and add in our  includes  and function but not the main  #include “EXTERN.h” #include perl.h” #include XSUB.h” #Include <stdio.h> void print_hi_ larry (void) { printf(“Hello  Larry !”);  } MODULE = Hi_ larry PACKAGE = Hi_ larry void print_hi_ larry ();
Now edit the Hi_ larry.pm package Hi_ larry ; use 5.008009; use strict; use warnings; Use base (qw(Exporter DynaLoader)) @EXPORT_OK our @EXPORT = qw(  print_hi_ larry () ); our $VERSION = '0.01'; 1; __END__
How about the test file as well use Test::More tests => 2; BEGIN { use_ok('Hi_larry') }; ok(Hi_ larry ::print_hi_ larry ,&quot;Hello  Larry &quot;)
Now everyones fab  Perl Makefile.PL c:\>nmake test And at the very end  t/Hi_larry....ok Files=1, Tests=2,  0 wallclock secs ( 0.00 cusr +  0.00 csys =  0.00 CPU) All tests successful <--John don't forget to Insert lines of compiler gobbliegook here -->
So what is going on? Well this really comes down to black majik and it  differs  form OS to OS and perl to perl lets just say 1) our XS code is converted to 'C' (xsubpp)  2) this code is compiled 3) that compiled code is then  transformed  into  something  that can be shared into our 'Perl'
Some more Black Majik We did get a generated '.c' file that you can look at that at your own peril. But how does xsubpp know how to get data back and forth between 'C' and 'Perl'. Well we know  everything  in Perl  is a struc so it is a rather simple trick. It uses a typemap.
Typemap Not much to it. A simple lookup table broken into three parts  Basic types unsigned Int T_UV unsigned Long  T_UV size_t T_UV STRLEN T_UV Input types T_UV $var =($type)SvUV($arg) Output  types T_UV   sv_setuv($arg,(UV)$var) Hey look at that we see perl guts again
To h2xs or not h2xs To start yes  Good  Beginnings  = Good Endings Keep It Simple Stupid Kiss Big differences between versions and systems What might be good for the writer of h2sx might not be good for you Get your 'C' to compile first For a straight Lib port Yeah OK
What is in an .XS Many ways to do  anything  and few rules Chaos is great isn't it Not quite 'Perl' and not  quite 'C' Not a Language A large set of 'C' macros that we can use Always  in upper case  and most times followed by a “:”
Anatomy of an xs file Starts with the three wise men #include &quot;EXTERN.h&quot; #include &quot;perl.h&quot; #include &quot;XSUB.h&quot; Next our C code or Not  In DBD::ORACLE there is none we compile it first and use #include &quot;Oracle.h&quot; As our only line of 'C' code in oracle.xs At  any  time we can do our old 'C' friend #ifdef
MODULE, PACKAGE, PREFIX, come next MODULE = Hi_ larry PACKAGE = Hi_ larry MODULE So anything before the first one is 'C' PACKAGE Says my XS code starts here Lets us organize our code We can switch them up so your code can be non- contiguous
MODULE = Apache  PACKAGE = Apache  PREFIX = mod_perl INCLUDE: Oracle.xsi We can name it  anything  we want as long as it is an xs file .xsi seems to be the norm PREFIX Does the opposite of what you would think Strips off the  prefix  from the 'XS' functions I. E. Apache.xs int mod_perl_sent_header(r, val=0) And in perl it is called as sent_header(r, val=0) Next!
Now your Xsub The  simplest  form has three parts A return value description And finally a description of the argument types  The name of the Xsub and its arguments print_hi_ larry (); void <--John rember to change this to one that has arguments -->
Some Examples #include <string.h> STRLEN strconcat(char* str1,char* str2, char* outstr){ strcpy(outstr, (const char*) srt1); strcat(outstr,(const char*) str2); return  strlen(outstr); } And now the XS part STRLEN strconcat(str1, str2) CODE: PREINIT: char* str1 char* str2 STRLEN length length = strlen( str1) + strlen(str2)+1; New(0,RETVAL,length,char); OUTPUT: RETVAL Safefree(RETVAL); CLEANUP: length = strconcat(str1,str2,RETVAL);
The Black Majik PREINIT: CODE: OUTPUT: RETVAL Lets you declare extra variables 'C' code follows me A special 'C' value just for you.  That  holds the 'return value' Gives us a way to clean any messes we made CLEANUP: Used with CODE: to send RETVAL back to 'Perl'
The Evil Dark Majik with a -6 saving throw Safefree(RETVAL); void  New(0,void* pointer, int length, type): Perl Guts This allocates some memory for us. New(0,RETVAL,length,char): length  is the new length we calculated char  is what it is void Safefree(void* pointer);  This deallocates some memory for us. RETVAL  which is a pointer to the memory we  allocated RETVAL  which is a pointer to the memory we  allocated
Interface Design Make it as Perlish as  possible my $length = strconcat($str1.$str2,$outstring); Is just plain bad. Do not supply what we already know my $fullname  = full_name($first,$len_first,$last,$len_last) Use PREFEX MODULE = OCI  PCKAGE = OCI SV oci_ping() Would come out in perl as OCI::oci_ping()
How About Summing an Array Here is our little 'C' that takes the number of ints to add, and an array of ints  typedef int intArray; int sum(int num, intArray *array){ int thesum =0; int thecount; for (count = 0; count <num;count++){ thesum += array[count]; } return thesum; }
And our XS int sum_a_list(array, ...) '...' is another XS thing meaning I do not know how many arguments there are IntArray * array Will not compile. A XS does not know what an 'IntArray' is. We solve this by adding our own typemap file in the build dir intArray *  T_ARRAY CODE: RETVAL = sum(ix_array,array); OUTPUT: RETVAL CLEANUP: Safefree(array); XS does know what a T_ARRAY is though
More Black Majik ix_array You might of noticed this little fellow '...' will create the 'itmes' value for you  automatically   This is the 'items' of the '...' that was passed in on the stack.  Int  not_number_count(...) CODE: for(i=0;i< itmes; i++){
The Stack We have our one Gut Macro just for called  ST(i) where i is the 0 based index of the stack We might as well talk about the 'stack' So in our last example if we add SV *sv = ST(i); As the next line. We would be saving a referace to the Stack value in a local SV called sv. One thing with the Stack is it normally have only one value  on the way back (RETVAL)  Until now!
Just Plain Eval Majik Many times in Perl we want to return a list of alternating keys and values Here is some of the XS code for this. %say_hi = Hello::say_hi_in('eu'); Print $say_hi{'french'}; void say_hi_in(local) char * local  PPCODE: switch (local) { case REGION_EU: EXTEND(SP,16); PUSHs(sv_2mortal(newSVpv(“french”,”Bonjour”))); PUSHs(sv_2mortal(newSVpv(“english”,”Hello”)));
The  explanation PPCODE: Tells XS that I will be creating  the return Stack EXTEND(SP,16); Tells XS to extend the  return  stack to 16 spots PUSHs(sv_2mortal(newSVpv(“french”,”Bonjour”))); PUSHs puts our value on the Stack sv_2mortal More Guts Majik.  In this case we have to tell 'Perl' that the new value we are pushing is Mortal as only copy of the sv is  assigned  in Perl.  So now they will be garbage collected. newSVpv Another  Guts macro that creates a SV from a string.
How about embedding PERL Surprisingly  easy #includes <EXTERN.h> #includes <perl.h> You Just include it. static PerlInterpreter *my_perl; int main(intargc,char **argv){ Char* command_line[] ={“”.”-e”,”print \”Hello C this is Larry  \\n\ ”;”}; } my_perl  = perl_alloc(); perl_constrct(my_perl); perl_run(my_perl); perl_parse(my_perl, NULL,3, command_line,(char **)NULL); perl_destruct(my_perl); perl_free(my_perl); return 0;
Where to go from here Well there is only 1 book Extending and Embedding Perl By Tim Jeness and Simon Cozens Steal from other people like I do
? Its not the Falling the hurts It is the sudden stop at the bottom that will kill you

More Related Content

ODP
How Xslate Works
ODP
Perl Moderno
PDF
Thnad's Revenge
PDF
Ruby for Java Developers
ODP
Red Flags in Programming
PDF
JRuby, Not Just For Hard-Headed Pragmatists Anymore
PPTX
Php Extensions for Dummies
PPTX
Php extensions
How Xslate Works
Perl Moderno
Thnad's Revenge
Ruby for Java Developers
Red Flags in Programming
JRuby, Not Just For Hard-Headed Pragmatists Anymore
Php Extensions for Dummies
Php extensions

What's hot (20)

ODP
Hom Class
ODP
Hom Class
ODP
Python 3000
PDF
Perl 5.10
PPTX
Php extensions
ODP
Python Compiler Internals Presentation Slides
PPT
Ruby For Java Programmers
PDF
Better rspec 進擊的 RSpec
PDF
Make Your Own Perl with Moops
PDF
The Perl API for the Mortally Terrified (beta)
ODP
Programming Under Linux In Python
PDF
Create your own PHP extension, step by step - phpDay 2012 Verona
PDF
SymfonyCon 2017 php7 performances
PDF
What we can learn from Rebol?
PPT
Airlover 20030324 1
PDF
A(n abridged) tour of the Rust compiler [PDX-Rust March 2014]
PDF
Building Custom PHP Extensions
PPTX
Writing and using php streams and sockets
PPT
Talk Unix Shell Script
PDF
Php and threads ZTS
Hom Class
Hom Class
Python 3000
Perl 5.10
Php extensions
Python Compiler Internals Presentation Slides
Ruby For Java Programmers
Better rspec 進擊的 RSpec
Make Your Own Perl with Moops
The Perl API for the Mortally Terrified (beta)
Programming Under Linux In Python
Create your own PHP extension, step by step - phpDay 2012 Verona
SymfonyCon 2017 php7 performances
What we can learn from Rebol?
Airlover 20030324 1
A(n abridged) tour of the Rust compiler [PDX-Rust March 2014]
Building Custom PHP Extensions
Writing and using php streams and sockets
Talk Unix Shell Script
Php and threads ZTS
Ad

Similar to Embed--Basic PERL XS (20)

ODP
Getting started with Perl XS and Inline::C
PPT
typemap in Perl/XS
PPTX
Perl bhargav
PPTX
programming language interface i.pptx
KEY
Yapcasia2011 - Hello Embed Perl
PDF
perltut
PDF
perltut
PPTX
Perl slid
PPTX
ODP
Embedding perl
PDF
newperl5
PDF
newperl5
PDF
Introduction to PERL Programming - Complete Notes
PPTX
File handle in PROGRAMMable extensible interpreted .pptx
PPT
Perl Development (Sample Courseware)
PDF
Perl-C/C++ Integration with Swig
PPT
Perl Reference.ppt
PPT
PERL - complete_Training_Modules_Ref.ppt
PPT
PERL - complete_guide_references (1).ppt
PDF
Advanced perl finer points ,pack&amp;unpack,eval,files
Getting started with Perl XS and Inline::C
typemap in Perl/XS
Perl bhargav
programming language interface i.pptx
Yapcasia2011 - Hello Embed Perl
perltut
perltut
Perl slid
Embedding perl
newperl5
newperl5
Introduction to PERL Programming - Complete Notes
File handle in PROGRAMMable extensible interpreted .pptx
Perl Development (Sample Courseware)
Perl-C/C++ Integration with Swig
Perl Reference.ppt
PERL - complete_Training_Modules_Ref.ppt
PERL - complete_guide_references (1).ppt
Advanced perl finer points ,pack&amp;unpack,eval,files
Ad

Embed--Basic PERL XS

  • 1. Perl XS By John Scoles The Pythian Group Black Art? Your Handy Friend ? Misunderstood Brain Sucking Zombie from Hell?
  • 2. My XS Story! The funny thing is the Chinese use the same word for catastrophe as they use for opportunity
  • 3. In The Beginning 1800+ line Makefile.PL 1000+ lines of XS 800+ lines of Perl 5300+ lines of pure 'C'
  • 4. My 'C' Background I can Spell 'c' correctly 87.654% of the time 18 times out of 20.
  • 5. My XS Background at the time Well I know of them! Bart Simpson said it best when asked if he knew long division or multiplication
  • 6. A Complete FNG NEWBIE RETARD Whatever
  • 7. So as Johny Cash would say I Fell into a Burning Ring of Fire
  • 9. So I went Looking for Answers What there was, wasn't much However I did learn 10 different ways to say “Hello World” What there was, didn't help much What there was, and still is, was dated What there was, usually ended with “ Read Perl Guts”
  • 10. Why Is This? This sums up the nature of XS programming There are 10 ways to do the same thing! None of them are 100% wrong None of them are 100% right
  • 11. Lets go back to the start We all know that Perl is written in 'C' Big Deal most languages are written in 'C' Most 'C' stuff will be familiar to a 'Perl' programmer Perl is very cozy with 'C'
  • 12. A Few Things to know about 'C' Can't do shit without a 'lib' “I stand on the shoulders of giants!” NANOS GIGANTIUM HUMERIS INSIDENTES Compiled Strictly Typed No Memory Management Function params are by value only
  • 13. A Few Things to say about Perl Interpreted Loosely Typed Managed Memory Function params are by 'Ref' only Perl is Just 'C' without types
  • 14. Stop, Look, Listen! What is it we are trying to do? Credits to Navy Beans it is already on CPAN Access an API Improve performance of Perl Link into a static Lib
  • 15. How about DBI and DBD::Oracle Access an API (OCI) for DBD::Oracle for sure 'C' for DBI to make it speedy for one 26 lines of code to do a fetch Way back in the dark days there was a direct link to OCI but it has died Now with Dynamic Linking no need for static perl
  • 16. Part the Second 'C' and 'Perl' in Detail Libs Memory Data
  • 17. Data in 'C' “ Those that go down to the 'C' in Structs” Defined Types (U32, oratext) Arrays of types (int[], char[]) Primitive types (int char etc) Structs (named collection of types)
  • 18. Struc struc say_hi_in { char* english; char* french; int* binary; } Must be declared at compile time It takes up a block of memory So an unitialized struc takes up the same space as an initialized one NOT A HASH!!!
  • 19. Memory in 'C' “ If it is the Captain's mess? Let him clean it up!” We have to do it. malloc free 'C' is dumb must know what type it is pointing to Pointers and such *,& and ** * a pointer to something & the value the Pointer is pointing to ** a pointer to a pointer char * name;
  • 20. Libs in 'C' Points to an Object file .obj, .o, .so, .dll or even an exe That can be shared A .h or 'header file' is not necessarily code it is just a promise of code needed at compile time. Usually just a prototype of the function or struct.
  • 21. Data in Perl Metadata struc sv { void* sv_any; U32 sv_refcnt; U32 sv_flags; } or Perl knows about itself. This is ' undef ' in Perl!!!!
  • 22. Our first look of the “Guts” of Perl struc sv { void* sv_any; U32 sv_refcnt; U32 sv_flags; } sv_any Is a pointer to any other of the 'Perl' strucs sv_refcnt A count of the number of times this struc has been referenced sv_flags Holds the metadata of a 'Perl' variable. It utilizes bit logic (bitmask)
  • 23. Memory in 'PERL' II When an object is referenced it is Incremented by one sv_refcnt When an object goes out of scope it is decremented by one (most times) (most times) When it reaches 0 it is garbage collected by Perl And the memory is freed
  • 24. Libs in 'Perl' A .pm file is code t hat can be shared .
  • 25. How 'C' and 'Perl' Work 'C' Source -> Compiler -> Machine Code 'Perl' Sour c e -> Interpreter -> Syntax Tree -> Interpreter -> Machine Code Syntax Tree-> {opcodes} = struc{} struc{} ->xsub pointer If this just happens to point to a 'C' function It will run
  • 26. Finally down to Brass Tacks Thank you good by:) X External S Subroutines eXternal Subroutines or XS
  • 27. Now Some Code Far be it form me to break with tradition #Include <stdio.h> void print_hi_larry(void) { printf(“Hello Larry!”); } Int main(int argc,char *argv[]){ print_hi_larry(); exit(0); } So to the left is hello Larry in 'C'
  • 28. How about a Perl File for it lib/Hi_ larry.pm Hi_ larry.xs Makefile.PL README t/test.t Changes MANIFEST Like most things in perl we have a Helper called h2sx In our case we do H2sx -A -n Hi_ larry And it generates all of our perl files thank you very much
  • 29. So all we do is open the .xs file and add in our includes and function but not the main #include “EXTERN.h” #include perl.h” #include XSUB.h” #Include <stdio.h> void print_hi_ larry (void) { printf(“Hello Larry !”); } MODULE = Hi_ larry PACKAGE = Hi_ larry void print_hi_ larry ();
  • 30. Now edit the Hi_ larry.pm package Hi_ larry ; use 5.008009; use strict; use warnings; Use base (qw(Exporter DynaLoader)) @EXPORT_OK our @EXPORT = qw( print_hi_ larry () ); our $VERSION = '0.01'; 1; __END__
  • 31. How about the test file as well use Test::More tests => 2; BEGIN { use_ok('Hi_larry') }; ok(Hi_ larry ::print_hi_ larry ,&quot;Hello Larry &quot;)
  • 32. Now everyones fab Perl Makefile.PL c:\>nmake test And at the very end t/Hi_larry....ok Files=1, Tests=2, 0 wallclock secs ( 0.00 cusr + 0.00 csys = 0.00 CPU) All tests successful <--John don't forget to Insert lines of compiler gobbliegook here -->
  • 33. So what is going on? Well this really comes down to black majik and it differs form OS to OS and perl to perl lets just say 1) our XS code is converted to 'C' (xsubpp) 2) this code is compiled 3) that compiled code is then transformed into something that can be shared into our 'Perl'
  • 34. Some more Black Majik We did get a generated '.c' file that you can look at that at your own peril. But how does xsubpp know how to get data back and forth between 'C' and 'Perl'. Well we know everything in Perl is a struc so it is a rather simple trick. It uses a typemap.
  • 35. Typemap Not much to it. A simple lookup table broken into three parts Basic types unsigned Int T_UV unsigned Long T_UV size_t T_UV STRLEN T_UV Input types T_UV $var =($type)SvUV($arg) Output types T_UV sv_setuv($arg,(UV)$var) Hey look at that we see perl guts again
  • 36. To h2xs or not h2xs To start yes Good Beginnings = Good Endings Keep It Simple Stupid Kiss Big differences between versions and systems What might be good for the writer of h2sx might not be good for you Get your 'C' to compile first For a straight Lib port Yeah OK
  • 37. What is in an .XS Many ways to do anything and few rules Chaos is great isn't it Not quite 'Perl' and not quite 'C' Not a Language A large set of 'C' macros that we can use Always in upper case and most times followed by a “:”
  • 38. Anatomy of an xs file Starts with the three wise men #include &quot;EXTERN.h&quot; #include &quot;perl.h&quot; #include &quot;XSUB.h&quot; Next our C code or Not In DBD::ORACLE there is none we compile it first and use #include &quot;Oracle.h&quot; As our only line of 'C' code in oracle.xs At any time we can do our old 'C' friend #ifdef
  • 39. MODULE, PACKAGE, PREFIX, come next MODULE = Hi_ larry PACKAGE = Hi_ larry MODULE So anything before the first one is 'C' PACKAGE Says my XS code starts here Lets us organize our code We can switch them up so your code can be non- contiguous
  • 40. MODULE = Apache PACKAGE = Apache PREFIX = mod_perl INCLUDE: Oracle.xsi We can name it anything we want as long as it is an xs file .xsi seems to be the norm PREFIX Does the opposite of what you would think Strips off the prefix from the 'XS' functions I. E. Apache.xs int mod_perl_sent_header(r, val=0) And in perl it is called as sent_header(r, val=0) Next!
  • 41. Now your Xsub The simplest form has three parts A return value description And finally a description of the argument types The name of the Xsub and its arguments print_hi_ larry (); void <--John rember to change this to one that has arguments -->
  • 42. Some Examples #include <string.h> STRLEN strconcat(char* str1,char* str2, char* outstr){ strcpy(outstr, (const char*) srt1); strcat(outstr,(const char*) str2); return strlen(outstr); } And now the XS part STRLEN strconcat(str1, str2) CODE: PREINIT: char* str1 char* str2 STRLEN length length = strlen( str1) + strlen(str2)+1; New(0,RETVAL,length,char); OUTPUT: RETVAL Safefree(RETVAL); CLEANUP: length = strconcat(str1,str2,RETVAL);
  • 43. The Black Majik PREINIT: CODE: OUTPUT: RETVAL Lets you declare extra variables 'C' code follows me A special 'C' value just for you. That holds the 'return value' Gives us a way to clean any messes we made CLEANUP: Used with CODE: to send RETVAL back to 'Perl'
  • 44. The Evil Dark Majik with a -6 saving throw Safefree(RETVAL); void New(0,void* pointer, int length, type): Perl Guts This allocates some memory for us. New(0,RETVAL,length,char): length is the new length we calculated char is what it is void Safefree(void* pointer); This deallocates some memory for us. RETVAL which is a pointer to the memory we allocated RETVAL which is a pointer to the memory we allocated
  • 45. Interface Design Make it as Perlish as possible my $length = strconcat($str1.$str2,$outstring); Is just plain bad. Do not supply what we already know my $fullname = full_name($first,$len_first,$last,$len_last) Use PREFEX MODULE = OCI PCKAGE = OCI SV oci_ping() Would come out in perl as OCI::oci_ping()
  • 46. How About Summing an Array Here is our little 'C' that takes the number of ints to add, and an array of ints typedef int intArray; int sum(int num, intArray *array){ int thesum =0; int thecount; for (count = 0; count <num;count++){ thesum += array[count]; } return thesum; }
  • 47. And our XS int sum_a_list(array, ...) '...' is another XS thing meaning I do not know how many arguments there are IntArray * array Will not compile. A XS does not know what an 'IntArray' is. We solve this by adding our own typemap file in the build dir intArray * T_ARRAY CODE: RETVAL = sum(ix_array,array); OUTPUT: RETVAL CLEANUP: Safefree(array); XS does know what a T_ARRAY is though
  • 48. More Black Majik ix_array You might of noticed this little fellow '...' will create the 'itmes' value for you automatically This is the 'items' of the '...' that was passed in on the stack. Int not_number_count(...) CODE: for(i=0;i< itmes; i++){
  • 49. The Stack We have our one Gut Macro just for called ST(i) where i is the 0 based index of the stack We might as well talk about the 'stack' So in our last example if we add SV *sv = ST(i); As the next line. We would be saving a referace to the Stack value in a local SV called sv. One thing with the Stack is it normally have only one value on the way back (RETVAL) Until now!
  • 50. Just Plain Eval Majik Many times in Perl we want to return a list of alternating keys and values Here is some of the XS code for this. %say_hi = Hello::say_hi_in('eu'); Print $say_hi{'french'}; void say_hi_in(local) char * local PPCODE: switch (local) { case REGION_EU: EXTEND(SP,16); PUSHs(sv_2mortal(newSVpv(“french”,”Bonjour”))); PUSHs(sv_2mortal(newSVpv(“english”,”Hello”)));
  • 51. The explanation PPCODE: Tells XS that I will be creating the return Stack EXTEND(SP,16); Tells XS to extend the return stack to 16 spots PUSHs(sv_2mortal(newSVpv(“french”,”Bonjour”))); PUSHs puts our value on the Stack sv_2mortal More Guts Majik. In this case we have to tell 'Perl' that the new value we are pushing is Mortal as only copy of the sv is assigned in Perl. So now they will be garbage collected. newSVpv Another Guts macro that creates a SV from a string.
  • 52. How about embedding PERL Surprisingly easy #includes <EXTERN.h> #includes <perl.h> You Just include it. static PerlInterpreter *my_perl; int main(intargc,char **argv){ Char* command_line[] ={“”.”-e”,”print \”Hello C this is Larry \\n\ ”;”}; } my_perl = perl_alloc(); perl_constrct(my_perl); perl_run(my_perl); perl_parse(my_perl, NULL,3, command_line,(char **)NULL); perl_destruct(my_perl); perl_free(my_perl); return 0;
  • 53. Where to go from here Well there is only 1 book Extending and Embedding Perl By Tim Jeness and Simon Cozens Steal from other people like I do
  • 54. ? Its not the Falling the hurts It is the sudden stop at the bottom that will kill you