xs fun
DESCRIPTION
A talk about XS Fun, an easy-going tutorial to Perl XS: https://github.com/xsawyerx/xs-fun This talk was originally given at Cluj.pm, on November 7th, 2013.TRANSCRIPT
XS is...A glue layer between Perl and C/C++Sections, macros, functionsRequires knowledge with C, Perl API, XS, typemapsWritten by our very bestComplex, difficult, strenuous, laborious, painful, formidable (additional words can be found in )An impediment to Modern Perl
thesaurus.com
XS ismisunderstood
No need to be an expertBasic Perl API is simpleXS is not too difficultLots of optionsAll documented
Except...... except those that aren't documented... except that the official tutorial sucks... except that there's no better (or any other full) tutorial(at least not one I could find)
XS FunA tutorial making XS funStarts easy, progresses slowlySplit to chapters, each taking a small taskA lot of explanations for beginnersAll examples work
Quick glossarySV = Scalar Value
Of:IV = Integer Value (my $i = -30)UV = Unsigned Integer Value (my $u = 3000...)NV = Double Value (my $d = 30.771)PV = String Value (my $s = 'hello world')SV = (another) Scalar Value
AH = Array Value (my @a = qw<hello world>)HV = Hash Value (my %h = ( hello => 'world' ))RV = Reference Value (my $hashref = \%h)That's it for now
XSFun.pmpackage XSFun;use strict;use warnings;
use Exporter;use XSLoader;
use base 'Exporter';
our $VERSION = '0.001';our %EXPORT_TAGS = ( 'all' => [qw<get_version>] );our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
XSLoader::load( 'XSFun', $VERSION );
1;
XSFun.xs#include "EXTERN.h"#include "perl.h"#include "XSUB.h"#include "ppport.h"
MODULE = XSFun PACKAGE = XSFun
doubleadd_numbers(double a, double b) CODE: RETVAL = a + b; OUTPUT: RETVAL
SV *add_numbers_perl(SV *a, SV *b) CODE: { const double sum = SvNV(a) + SvNV(b); RETVAL = newSVnv(sum); } OUTPUT: RETVAL
XSFun.xs (more)#include <chromaprint.h>
/* in the code section */const char *get_version() CODE: RETVAL = chromaprint_get_version(); OUTPUT: RETVAL
# in version.t:
use XSFun ':all';is( get_version(), '6.0.0', 'chromaprint version is 6.0.0' );
t/version.t .. okAll tests successful.Files=1, Tests=1, 0 wallclock secs ( 0.03 usr 0.01 sys + 0.02 cusr 0.00 csys = 0.06 CPU)Result: PASS
Audio/Chromaprint.pmpackage Audio::Chromaprint;
use strict;use warnings;use XSLoader;
our $VERSION = '0.001';
XSLoader::load( 'Audio::Chromaprint', $VERSION );
1;
Chromaprint.xs#include "EXTERN.h"#include "perl.h"#include "XSUB.h"#include "ppport.h"
#include <chromaprint.h>
MODULE = Audio::Chromaprint PACKAGE = Audio::Chromaprint
Chromaprint.xsconst char *version(SV *self) CODE: RETVAL = chromaprint_get_version(); OUTPUT: RETVAL
Constructor# In Perl:sub new { bless {}, shift }
# or...sub new { my $class = shift; # or $_[0] my %hash = (); my $self = \%hash; return bless $self, $class;}
# Pure-Perlsub new { my $class = shift; # or $_[0] my %hash = (); my $self = \%hash; return bless $self, $class;}
/* in XS */SV *new( const char *class ) CODE: /* Create a hash */ HV* hash = newHV();
/* Create a reference to the hash */ SV* const self = newRV_noinc( (SV *)hash );
/* bless into the proper package */ RETVAL = sv_bless( self, gv_stashpv( class, 0 ) ); OUTPUT: RETVAL