embed--basic perl xs
TRANSCRIPT
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 that can be shared.
How 'C' and 'Perl' Work
'C'
Source ->
Compiler ->
Machine Code
'Perl'
Source ->
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
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
void print_hi_larry(void) {
printf(Hello Larry!);
}
MODULE = Hi_larryPACKAGE = 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,"Hello Larry")
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