81
Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough [email protected]

Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough [email protected]

Embed Size (px)

Citation preview

Page 1: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Running Away to C

XS – More faff than fearLondon Perl Workshop – Dec 04

Alex [email protected]

Page 2: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

You’re here because…

• You know some Perl

• You recognise some C– But fear it a little

• You’re an evil brigand

• You know it’s warmer in here

Page 3: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 4: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 5: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 6: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 7: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 8: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 9: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 10: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 11: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 12: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 13: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 14: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 15: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 16: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 17: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack

Page 18: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Stack Functions

dSP; Declare stack varsPUSHMARK(SP) start of argumentsEXTEND make spaceXPUSHstuff push stuff, making spacePUSHstuff push stuff, need spacePUTBACK done adding arguments . . . Make a call . . .SPAGAIN refresh our stackret = POPstuff grab stuff from stackPUTBACK we’re done grabbing stuff

Page 19: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Scope•Start and end a scope

•Tell Perl we’re creating temporary stuff

•Tell Perl when we’re done with it

Page 20: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Scope Functions

ENTER Opening brace {SAVETMPS start making temps . . . Call function . . .FREETMPS done with my tempsLEAVE Closing brace }

Page 21: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Scalars

$thing = 12 12.3 “harry” \ @array \ %hash \ $thing bless(\$object) *FILE qr{.*} {code}

Page 22: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Scalar Functions ISV* get_sv(char* name, I32 create)SV* sv = get_sv(“bar”, TRUE)

SV* newSVx sv = newSViv(12) newSVnv(12.3) newSVpv(“honk”, 0) -> “honk” newSVpv(“honk”, 2) -> “ho”

IV intv = SvIV(sv)NV fltv = SvNV(sv)char* foo = SvPV(sv)

sv_setpv(sv, “honk”); sv_setiv(sv, 12)

Page 23: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Scalar Functions ISV* get_sv(char* name, I32 create)SV* sv = get_sv(“bar”, TRUE)

SV* newSVx sv = newSViv(12) newSVnv(12.3) newSVpv(“honk”, 0) -> “honk” newSVpv(“honk”, 2) -> “ho”

IV intv = SvIV(sv)NV fltv = SvNV(sv)char* foo = SvPV(sv)

sv_setpv(sv, “honk”); sv_setiv(sv, 12)

Page 24: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Scalar Functions ISV* get_sv(char* name, I32 create)SV* sv = get_sv(“bar”, TRUE)

SV* newSVx sv = newSViv(12) newSVnv(12.3) newSVpv(“honk”, 0) -> “honk” newSVpv(“honk”, 2) -> “ho”

IV intv = SvIV(sv)NV fltv = SvNV(sv)char* foo = SvPV(sv)

sv_setpv(sv, “honk”); sv_setiv(sv, 12)

Page 25: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Scalar Functions ISV* get_sv(char* name, I32 create)SV* sv = get_sv(“bar”, TRUE)

SV* newSVx sv = newSViv(12) newSVnv(12.3) newSVpv(“honk”, 0) -> “honk” newSVpv(“honk”, 2) -> “ho”

IV intv = SvIV(sv)NV fltv = SvNV(sv)char* foo = SvPV(sv)

sv_setpv(sv, “honk”); sv_setiv(sv, 12)

Page 26: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Scalar Functions IISV* refsv = newRV_inc(sv) “refsv = \ sv”SV* sv = SvRV(refsv) “sv = $ { refsv }”

I32 cnt = REFCNT(sv) REFCNT_inc(sv) REFCNT_dec(sv)

SV *sv = sv_2mortal(newSViv(12))

sv_free(sv)

sv_{catpv catsv cmp dec eq inc isa len . . . }

Page 27: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Scalar Functions IISV* refsv = newRV_inc(sv) “refsv = \ sv”SV* sv = SvRV(refsv) “sv = $ { refsv }”

I32 cnt = REFCNT(sv) REFCNT_inc(sv) REFCNT_dec(sv)

SV *sv = sv_2mortal(newSViv(12))

sv_free(sv)

sv_{catpv catsv cmp dec eq inc isa len . . . }

Page 28: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Scalar Functions IISV* refsv = newRV_inc(sv) “refsv = \ sv”SV* sv = SvRV(refsv) “sv = $ { refsv }”

I32 cnt = REFCNT(sv) REFCNT_inc(sv) REFCNT_dec(sv)

SV *sv = sv_2mortal(newSViv(12))

sv_free(sv)

sv_{catpv catsv cmp dec eq inc isa len . . . }

Page 29: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Scalar Functions IISV* refsv = newRV_inc(sv) “refsv = \ sv”SV* sv = SvRV(refsv) “sv = $ { refsv }”

I32 cnt = REFCNT(sv) REFCNT_inc(sv) REFCNT_dec(sv)

SV *sv = sv_2mortal(newSViv(12))

sv_free(sv)

sv_{catpv catsv cmp dec eq inc isa len . . . }

Page 30: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

A Puzzle

• Find the longest set of three words that when listed form three letter words down all columns.

padsareatend

Page 31: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Array FunctionsAV *av = get_av(“ARGV”, TRUE)

SV** ret = av_store(av, 12, sv)

SV** ret = av_fetch(av, 12, sv, lval)

SV* sv = av_pop(av) av_shift(av)

void av_push(av, sv) av_unshift(av, 3) [3 undefs]

I32 len = av_len(av)

Page 32: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Hash FunctionsHV *hv = get_hv(“hash”, TRUE)

BOOL hv_exists(hv, “key”, 3)

SV** sv = hv_fetch(hv, “key”, 3, lval)

SV** sv = hv_store(hv, “key”, 3, sv, 0)

Or you can play with HE (Hash Entries)

Page 33: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Function FunctionsCV* cv = get_cv(“subname”, TRUE)

call_pv(“subname”, context) call_sv(sv, context)

Context: G_VOID } G_SCALAR } context G_ARRAY } G_NOARGS no arguments G_DISCARD “no return values” G_EVAL catch die in eval { } G_KEEPERR .. and be nice to $@

Page 34: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Objects, globs, whatever

• Maybe you’ll need them

• Maybe you won’t

• See perlapi, perlcall, perlguts

Page 35: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Embedding

• You have some C

• You want to add a bit of Perl– Config file dabbling– Scripting engine– Hook into Efficient / Legacy code– Prototype features

Page 36: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Config Parsing

• Flexible configuration framework• C side factored into:

void get_config(char* key, char* dst, int len);

• Let Perl provide the intelligence

• (We provide the glue)

Page 37: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Perl

• A big C program

• A really tiny main()– Constructs an intepreter– Tells it to parse your script– Tells it to run your script

• Jumps between C and Perl a lot

– Cleans up (sort of)– Exits

Page 38: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Config Parsinguse strict;

my %config = ();

sub init {my($file) = @_;… # fill in %config

}

sub get_value {my($key) = @_;return $config{$key} || “”;

}

Page 39: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

#include "EXTERN.h"#include "Perl.h"

static PerlInterpreter *g_perl_interp;

int main(int argc, char** argv, char** env) {char *config_pl[] = {“config.pl”, 0};

PERL_SYS_INIT3(&argc,&argv,&env); g_perl_interp = perl_alloc();perl_construct(g_perl_interp);PL_exit_flags |= PERL_EXIT_DESTRUCT_END;perl_parse(g_perl_interp, NULL, 1, config_pl, env);perl_run(g_perl_interp);

do_program_stuff(. . .);

perl_destruct(g_perl_interp);perl_free(g_perl_interp);PERL_SYS_TERM()

}

Page 40: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

#include "EXTERN.h"#include "Perl.h"

static PerlInterpreter *g_perl_interp;

int main(int argc, char** argv, char** env) {char *config_pl[] = {“config.pl”, 0};

PERL_SYS_INIT3(&argc,&argv,&env); g_perl_interp = perl_alloc();perl_construct(g_perl_interp);PL_exit_flags |= PERL_EXIT_DESTRUCT_END;perl_parse(g_perl_interp, NULL, 1, config_pl, env);perl_run(g_perl_interp);

do_program_stuff(. . .);

perl_destruct(g_perl_interp);perl_free(g_perl_interp);PERL_SYS_TERM()

}

Page 41: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

#include "EXTERN.h"#include "Perl.h"

static PerlInterpreter *g_perl_interp;

int main(int argc, char** argv, char** env) {char *config_pl[] = {“config.pl”, 0};

PERL_SYS_INIT3(&argc,&argv,&env); g_perl_interp = perl_alloc();perl_construct(g_perl_interp);PL_exit_flags |= PERL_EXIT_DESTRUCT_END;perl_parse(g_perl_interp, NULL, 1, config_pl, env);perl_run(g_perl_interp);

do_program_stuff(. . .);

perl_destruct(g_perl_interp);perl_free(g_perl_interp);PERL_SYS_TERM()

}

Page 42: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

#include "EXTERN.h"#include "Perl.h"

static PerlInterpreter *g_perl_interp;

int main(int argc, char** argv, char** env) {char *config_pl[] = {“config.pl”, 0};

PERL_SYS_INIT3(&argc,&argv,&env); g_perl_interp = perl_alloc();perl_construct(g_perl_interp);PL_exit_flags |= PERL_EXIT_DESTRUCT_END;perl_parse(g_perl_interp, NULL, 1, config_pl, env);perl_run(g_perl_interp);

do_program_stuff(. . .);

perl_destruct(g_perl_interp);perl_free(g_perl_interp);PERL_SYS_TERM()

}

Page 43: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

#include "EXTERN.h"#include "Perl.h"

static PerlInterpreter *g_perl_interp;

int main(int argc, char** argv, char** env) {char *config_pl[] = {“config.pl”, 0};

PERL_SYS_INIT3(&argc,&argv,&env); g_perl_interp = perl_alloc();perl_construct(g_perl_interp);PL_exit_flags |= PERL_EXIT_DESTRUCT_END;perl_parse(g_perl_interp, NULL, 1, config_pl, env);perl_run(g_perl_interp);

do_program_stuff(. . .);

perl_destruct(g_perl_interp);perl_free(g_perl_interp);PERL_SYS_TERM()

}

Page 44: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

#include "EXTERN.h"#include "Perl.h"

static PerlInterpreter *g_perl_interp;

int main(int argc, char** argv, char** env) {char *config_pl[] = {“config.pl”, 0};

PERL_SYS_INIT3(&argc,&argv,&env); g_perl_interp = perl_alloc();perl_construct(g_perl_interp);PL_exit_flags |= PERL_EXIT_DESTRUCT_END;perl_parse(g_perl_interp, NULL, 1, config_pl, env);perl_run(g_perl_interp);

do_program_stuff(. . .);

perl_destruct(g_perl_interp);perl_free(g_perl_interp);PERL_SYS_TERM()

}

Page 45: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

void get_config(char* key, char* dst) {dSP;SV *ret = NULL;

ENTER;SAVETMPS;PUSHMARK(SP);

XPUSHs(sv_2mortal(newSVpv(key)));PUTBACK;call_pv("get_value", G_SCALAR); SPAGAIN;ret = POPs;strcpy(dst, SvPV);PUTBACK;FREETMPS;LEAVE;

}

Page 46: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

void get_config(char* key, char* dst) {dSP;SV *ret = NULL;

ENTER;SAVETMPS;PUSHMARK(SP);

XPUSHs(sv_2mortal(newSVpv(key)));PUTBACK;call_pv("get_value", G_SCALAR); SPAGAIN;ret = POPs;strcpy(dst, SvPV);PUTBACK;FREETMPS;LEAVE;

}

Page 47: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

void get_config(char* key, char* dst) {dSP;SV *ret = NULL;

ENTER;SAVETMPS;PUSHMARK(SP);

XPUSHs(sv_2mortal(newSVpv(key)));PUTBACK;call_pv("get_value", G_SCALAR); SPAGAIN;ret = POPs;strcpy(dst, SvPV);PUTBACK;FREETMPS;LEAVE;

}

Page 48: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

void get_config(char* key, char* dst) {dSP;SV *ret = NULL;

ENTER;SAVETMPS;PUSHMARK(SP);

XPUSHs(sv_2mortal(newSVpv(key)));PUTBACK;call_pv("get_value", G_SCALAR); SPAGAIN;ret = POPs;strcpy(dst, SvPV);PUTBACK;FREETMPS;LEAVE;

}

Page 49: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

void get_config(char* key, char* dst) {dSP;SV *ret = NULL;

ENTER;SAVETMPS;PUSHMARK(SP);

XPUSHs(sv_2mortal(newSVpv(key)));PUTBACK;call_pv("get_value", G_SCALAR); SPAGAIN;ret = POPs;strcpy(dst, SvPV);PUTBACK;FREETMPS;LEAVE;

}

Page 50: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

void get_config(char* key, char* dst) {dSP;SV *ret = NULL;

ENTER;SAVETMPS;PUSHMARK(SP);

XPUSHs(sv_2mortal(newSVpv(key)));PUTBACK;call_pv("get_value", G_SCALAR); SPAGAIN;ret = POPs;strcpy(dst, SvPV);PUTBACK;FREETMPS;LEAVE;

}

Page 51: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

void get_config(char* key, char* dst) {dSP;SV *ret = NULL;

ENTER;SAVETMPS;PUSHMARK(SP);

XPUSHs(sv_2mortal(newSVpv(key)));PUTBACK;call_pv("get_value", G_SCALAR); SPAGAIN;ret = POPs;strcpy(dst, SvPV);PUTBACK;FREETMPS;LEAVE;

}

Page 52: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Compiling

• Compile as normal, but add flags

cc -c foo.c \ `perl -MExtUtils::Embed -e ccopts`

cc -o interp perlxsi.o interp.o \ `perl -MExtUtils::Embed -e ldopts`

Page 53: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Compiling – Win32

• For Visual Studio & ActivePerlinclude: C:\Perl\lib\CORE

lib dir: C:\Perl\lib\CORE

libs: Perl58.lib

+ have C:\Perl\bin\ in path for dll when running.

Page 54: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Using Modules

• Pure Perl(eg. Acme::Barf)

• XS extensions(eg. Audio::File, Storable)

• Can do, but need to set up dynaloader from C first…

Page 55: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Using Modules

• Dynaloader loads and initialises C modules when you say“use Foo”

• Dynaloader must be setup first

• Then everything should Just Work

Page 56: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

DynaloaderEXTERN_C void xs_init (pTHX);EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);

EXTERN_C void xs_init(pTHX) {char *file = __FILE__;dXSUB_SYS;

newXS("DynaLoader::boot_DynaLoader",boot_DynaLoader, file);

}

And change your call to perl_parse to:perl_parse(g_perl_interp, xs_init, 1, config_pl, env);

Generate this with:perl -MExtUtils::Embed -e xsinit -- -o perlxsi.c

Page 57: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

DynaloaderEXTERN_C void xs_init (pTHX);EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);

EXTERN_C void xs_init(pTHX) {char *file = __FILE__;dXSUB_SYS;

newXS("DynaLoader::boot_DynaLoader",boot_DynaLoader, file);

}

And change your call to perl_parse to:perl_parse(g_perl_interp, xs_init, 1, config_pl, env);

Generate this with:perl -MExtUtils::Embed -e xsinit -- -o perlxsi.c

perl -MExtUtils::Embed -e xsinit -- -o perlxsi.c

Page 58: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Manual Pages

• perlembed

• perlcall

• perlapi

• ExtUtils::Embed

Page 59: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

XS

• C from Perl

• libraries

• Meddle

• Speed

Page 60: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Libraries• Steal work from others

• Compile & install separately

• XS provides glue to Perl

• Provide a Perl module to improve interface

Page 61: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Library’s Header File// green.h – Interface to green-turtle library

GREEN* new_green(int turtles, char *message);

int free_green(GREEN *green);

int more_turtles(GREEN *green, int eggs);

char** turtles(GREEN *green, char *match);

Page 62: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

h2xs

• header 2 XS

• First install your library & headers(so that green.h is in the standard search path)

• Run: h2xs –Oxn Green::Turtle green.h

• Copy green.h to Green/Turtle

• Run: h2xs –Oxn Green::Turtle green.h

Page 63: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

h2xs

• This just went and created

• Turtle.pm – Perl template

• Turtle.xs – XS functions

• typemap – maps C types to Perl types

• Makefile.PL

• Some test files and other stuff

• Nearly works… but we have to faff first

Page 64: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Turtle.xs

• Headers (#include <green.h>)

MODULE = Green::Turtle PACKAGE = Green::Turtle

• XS “functions”

Page 65: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Turtle.xsMODULE = Green::Turtle PACKAGE = Green::Turtle

doubleconstant(name,arg) char * name int arg

GREEN *new_green(turtles, message) int turtles char * message

intfree_green(green) GREEN * green

. . .

Page 66: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Turtle.xsGREEN *new_green(turtles, message) int turtles char * message

Becomes:

Green::Turtle::new_green()

Page 67: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

typemap

GREEN* T_PTROBJ

Perl will “cast” between scalars & GREEN*

These scalars will be blessed into the GREENPtr package.

When destroyed, memory will not be free’d (but see later).

Page 68: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Turtle.pm

• Normal perl module + some imports

• Good idea to wrap the XS:sub new { my($class) = shift; my($turtles, $msg) = @_; my $self = {}; $self->{_green} = new_green($turtles, $msg); return bless $self, $class;}

sub add_turtles { my($self) = shift; return more_turtles($self->{green}, @_);}

Page 69: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

GREEN*

• GREEN* blessed into GREENPtr

• To free, we need to add a DESTROY()

MODULE Green::Turtle PACKAGE GREENPtr

voidDESTROY(green)

GREEN* greenCODE:

free_green(green)

Page 70: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

char **

• Perl doesn’t really know what to do so

• is not helpful…

• Can typemap or marshall ourselves, as we’ll want a list of strings, we’ll need to marshall.

char **turtles(green, message) GREEN * green char * message

Page 71: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

voidturtles(green, message) GREEN * green char * message PPCODE: { char **ret = turtles(green, message); while (*ret != NULL) { PUSHs(sv_2mortal(newSVpv(*ret, 0))); ret++; } }

Page 72: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

XS blocksintcount_colours(turtle)

GREEN* turtlePREINIT:char *name = “george”;CODE:RETVAL = reds(turtle, name)

+ greens(turtle, name);OUTPUT:RETVAL

Page 73: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

sub try_words { my($ar,$l,@all,$j) = $_[0];

push(@all, [split "", $_]) foreach @$ar; foreach my $a1 (@all) { foreach my $a2 (@all) { INNA: foreach my $a3 (@all) { for ($j=0;$j<$l;$j++) {

my $w = $a1->[$j].$a2->[$j].$a3->[$j];

unless (exists($w3{$w})){ next INNA; } }

print(join("", @$_)) foreach ($a1, $a2, $a3); print "\n"; } } }

}

Page 74: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

sub try_words { my($ar,$l,@all,$j) = $_[0];

push(@all, [split "", $_]) foreach @$ar; foreach my $a1 (@all) { foreach my $a2 (@all) { INNA: foreach my $a3 (@all) { for ($j=0;$j<$l;$j++) {

my $w = $a1->[$j].$a2->[$j].$a3->[$j];

unless (exists($w3{$w})){ next INNA; } }

print(join("", @$_)) foreach ($a1, $a2, $a3); print "\n"; } } }

}

Page 75: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

sub try_words { my($ar,$l,@all,$j) = $_[0];

# push(@all, [split "", $_]) foreach @$ar; foreach my $a1 (@$ar) { foreach my $a2 (@$ar) { INNA: foreach my $a3 (@$ar) { if (try_cwords($a1,$a2,$a3,$l,\%w3) ) { print “($a1, $a2, $a3)\n”; } } }

}

Page 76: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

inttry_cwords(one,two,thr,len,ref_w3) char* one char* two char* thr int len SV* ref_w3 PREINIT: int i; char three[] = {0,0,0}; HV* w3;

Page 77: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

char three[3]; char *one, *two, *thr; SV* ref_w3; HV* w3; int len;

CODE: if (! SvROK(ref_w3)) croak("ref_w3 is not a reference");

w3 = (HV*)SvRV(ref_w3);

for (i=0;i<len; i++) { three[0] = one[i]; three[1] = two[i]; three[2] = thr[i]; /* Check if it's in the hash */ if (!hv_exists(w3, three, 3)) XSRETURN_UNDEF; } RETVAL = 1;

Page 78: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

sub try_words { my($ar,$l,@all,$j) = $_[0];

# push(@all, [split "", $_]) foreach @$ar; foreach my $a1 (@$ar) { foreach my $a2 (@$ar) { INNA: foreach my $a3 (@$ar) { if (try_cwords($a1,$a2,$a3,$l,\%w3) ) { print “($a1, $a2, $a3)\n”; } } }

}

Page 79: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

C speed hotness

anticoagulativeneuroanatomicaldeterminateness

aeromechanicalaminoguanidineheterophylesis

Page 80: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

General XS info

• Lovely man pages– perlxs– perlxstut– perlcall, perlapi, perlwhatever

• Bother someone you know

• Inline::C!

• Inline::C!

Page 81: Running Away to C XS – More faff than fear London Perl Workshop – Dec 04 Alex Gough alex@earth.li

Lear on Hybrids

Our mother was the Pussy-cat, our father was the Owl, And so we're partly little beasts and partly little fowl,

The brothers of our familyhave feathers and they hoot, While all the sisters dress in fur and have long tails to boot.