writing perl extensions: there’s more than one way to do it
TRANSCRIPT
![Page 1: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/1.jpg)
Writing Perl Extensions:There’s more than one way to do it.
![Page 2: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/2.jpg)
Why write an extension?
• speed
• reuse legacy code or libraries written in other languages
• add new language features
• example: The Perl Data Language
![Page 3: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/3.jpg)
What is an extension?• Compiled code which can be loaded (usually
dynamically) into a Perl program.
your_extension.pm:...require DynaLoader;bootstrap your_extension;...
• loads shared library -- @INC/auto/your_extension/libyour_extension.{ a so dll }
• Now functions from that shared library can be called as you would call Perl functions.
![Page 4: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/4.jpg)
Methods of writing an extension.
• write raw C code yourself
• use XS to glue your C code and perl
• use swig to create multi-language glue
• use Inline::C to do *all* the work for you
• use PDL::PP to create PDL aware XS code
![Page 5: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/5.jpg)
what we’re going to do.
• Write and extension which executes C code which looks like this:
char * hello(char * who) {
char * message = malloc(...);sprintf(message,”Hello %s\n”,who);return message;
}
Which does the equivilant ofsub hello { return “Hello $_[0]\n”; }
![Page 6: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/6.jpg)
Write your extension manually in C.
#include "EXTERN.h"#include "perl.h"#include "XSUB.h"
XS(XS_your_extension_hello) { dXSARGS; if (items != 1)
Perl_croak(aTHX_ "Usage: your_extension::hello(who)"); {
char * who = (char *)SvPV(ST(0),PL_na);char * RETVAL;dXSTARG;
RETVAL = malloc(100 * (sizeof (char)));sprintf(RETVAL, "hello %s\n",who);
sv_setpv(TARG, RETVAL); XSprePUSH; PUSHTARG; } XSRETURN(1);}
XS(boot_your_extension) { dXSARGS; char* file = __FILE__; XS_VERSION_BOOTCHECK ; newXS("your_extension::hello", XS_your_extension_hello, file); XSRETURN_YES;}
![Page 7: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/7.jpg)
Write a .xs file and use xsubpp to do most of the work for you.
#include "EXTERN.h"#include "perl.h"#include "XSUB.h"
MODULE = your_extension PACKAGE = your_extension
char * hello(who);char * who;
CODE:RETVAL = malloc(100 * (sizeof (char)));sprintf(RETVAL, "hello %s\n",who);
OUTPUT:RETVAL
![Page 8: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/8.jpg)
XS has a learning curve...
• perldoc perlxs and perlxstut (the xs tutorial) to learn lots of crazy things about .xs files.
• knowing perlguts and perlapi also helps.
![Page 9: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/9.jpg)
Use h2xs to make your .xs file from a header file.
• h2xs will scan a C .h file and do the right thing ™ to create the appropriate glue code to link your C functions and Perl.
• Always start with h2xs anyway, even if you’re not using xs -- because it sets up a Makefile.PL.
![Page 10: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/10.jpg)
Use swig to create simpler, multi-language interfaces.
• xs is very specific to Perl and its internals, you end up getting your hands dirty with it… useful sometimes but not always necessary.
• swig extensions can be easily be retarget’d to Python, Scheme, Guile, Tcl and Java.
![Page 11: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/11.jpg)
SWIG:Simplified Wrapper and Interface Generator
>swig -perl5 example.icreates => example.pm , example_wrap.c , example.doc
Must compile manually or use MakeMaker.pm to write a Makefile for you.
>gcc example.c # compile your file>gcc example_wrap.c -I<perl-header-location>>ld -shared example.o example_wrap.o -o example.so
![Page 12: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/12.jpg)
What SWIG does for you.
• Your C functions can be now called from perl. You can specify default arguments in the interface file.
• Global variables and #defined constants become package variables.
----example.i----- ---- example.pm -----
%module example use exampleint foo(int a); &example::foo(5)void bar(double, double b=3.0); &example:bar(4.4)double foobar; $example::foobar#define barfoo 5 $example::barfoo
![Page 13: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/13.jpg)
SWIG features.
• doubles, ints, char *, etc. get passed around as you would expect (and hope).
• pointers get passed to and from perl as blessed references ($$ref is C pointer).
• special magic exists for accessing C arrays.
• perl “shadow classes” may be used interface to C structs and C++ classes.
![Page 14: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/14.jpg)
Make your life simpler with Inline
use Inline C;
print "9 + 16 = ", add(9, 16), "\n"; print "9 - 16 = ", subtract(9, 16), "\n";
__END__ __C__ int add(int x, int y) { return x + y; } int subtract(int x, int y) { return x - y; }
![Page 15: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/15.jpg)
more Inline
perl -e 'use Inline C=>q/void greet(){printf("Hello, world\n");}/;greet'
![Page 16: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/16.jpg)
Inline.pm
• uses Inline::<language>.pm to do all the work based on the language you specify.
• supports: passing of various data types, multiple return values, variable argument lists, and if you’re really crazy, evaluation of C code at runtime.
![Page 17: Writing Perl Extensions: There’s more than one way to do it](https://reader036.vdocuments.us/reader036/viewer/2022071718/56649ebf5503460f94bc9f8e/html5/thumbnails/17.jpg)
A few short words about the PDL preprocessor.
In the file example.pd:
pp_def( ‘sumover’,Pars => ‘a(n); [o] b();’,Code => ‘
double tmp=0;loop(n) %{
tmp += $a();%}$b() = tmp;’
);
• There’s also an Inline::PDLpp version.