Slides

12 downloads 512 Views 764KB Size Report
CODE: if (items > 1) rect->x = SvIV(ST(1));. RETVAL = rect->x;. OUTPUT: RETVAL .... unix > swig -python exam
binding C libraries

A journey

why?

how?

Perl 5 XS

#include #include "EXTERN.h" "EXTERN.h" #include #include "perl.h" "perl.h" #include #include "XSUB.h" "XSUB.h" #include #include "ppport.h" "ppport.h" #include #include MODULE MODULE == SDL::Rect SDL::Rect

PACKAGE PACKAGE == SDL::Rect SDL::Rect PREFIX PREFIX == rect_ rect_

SDL_Rect SDL_Rect ** rect_new rect_new (CLASS, (CLASS, x, x, y, y, w, w, h) h) char char** CLASS CLASS Sint16 Sint16 x, x, yy Uint16 Uint16 w, w, hh CODE: CODE: RETVAL RETVAL == (SDL_Rect (SDL_Rect *)safemalloc(sizeof(SDL_Rect)); *)safemalloc(sizeof(SDL_Rect)); RETVAL->x RETVAL->x == x; x; RETVAL->y RETVAL->y == y; y; RETVAL->w RETVAL->w == w; w; RETVAL->h RETVAL->h == h; h; OUTPUT: OUTPUT: RETVAL RETVAL

Sint16 Sint16 rect_x rect_x (( rect, rect, ... ... )) SDL_Rect SDL_Rect *rect *rect CODE: CODE: if if (items (items >> 11)) rect->x rect->x == SvIV(ST( SvIV(ST(11)); )); RETVAL RETVAL == rect->x; rect->x; OUTPUT: OUTPUT: RETVAL RETVAL Sint16 Sint16 rect_y rect_y (( rect, rect, ... ... )) SDL_Rect SDL_Rect *rect *rect CODE: CODE: if if (items (items >> 11)) rect->y rect->y == SvIV(ST( SvIV(ST(11)); )); RETVAL RETVAL == rect->y; rect->y; OUTPUT: OUTPUT: RETVAL RETVAL

SV SV ** createDocument( createDocument( CLASS, CLASS, version= version="1.0" "1.0",, encoding=NULL encoding=NULL )) char char ** version version char char ** encoding encoding ALIAS: ALIAS: XML::LibXML::Document::new XML::LibXML::Document::new == 11 PREINIT: PREINIT: xmlDocPtr xmlDocPtr doc=NULL; doc=NULL; CODE: CODE: PERL_UNUSED_VAR(ix); PERL_UNUSED_VAR(ix); doc doc == xmlNewDoc((const xmlNewDoc((const xmlChar*)version); xmlChar*)version); if if (encoding (encoding && && *encoding *encoding != != 00)) {{ doc->encoding doc->encoding == (xmlChar (xmlChar *)xmlStrdup((xmlChar *)xmlStrdup((xmlChar *)encoding); *)encoding); }} RETVAL RETVAL == PmmNodeToSv(INT2PTR(xmlNodePtr,doc),NULL); PmmNodeToSv(INT2PTR(xmlNodePtr,doc),NULL); OUTPUT: OUTPUT: RETVAL RETVAL

void void lmx_add( lmx_add( manager, manager, bag bag )) SDLx_LayerManager SDLx_LayerManager *manager *manager SV* SV* bag bag CODE: CODE: if if(( sv_isobject(bag) sv_isobject(bag) && && (SvTYPE(SvRV(bag)) (SvTYPE(SvRV(bag)) == == SVt_PVMG) SVt_PVMG) )) {{ SDLx_Layer SDLx_Layer *layer *layer == (SDLx_Layer (SDLx_Layer *)bag2obj(bag); *)bag2obj(bag); layer->index == av_len( layer->index av_len( manager->layers manager->layers )) ++ 11;; layer->manager == manager; layer->manager manager; layer->touched == 11;; layer->touched av_push( av_push( manager->layers, manager->layers, bag); bag); SvREFCNT_inc(bag); SvREFCNT_inc(bag); }}

Perl 5 XS C support

yes

C++ support

no

Compiler needed

yes

pro

- mature - no runtime penalty

contra

- very good C knowledge and a C compiler needed

?

?

?

Perl 5 XSpp

%{ %{ #include #include %} %} %module{Box2D}; %module{Box2D}; %name{Box2D::b2Shape} %name{Box2D::b2Shape} class class b2Shape b2Shape {{ %{ %{ void void b2Shape::ComputeAABB( b2Shape::ComputeAABB( aabb, aabb, xf xf )) b2AABB* b2AABB* aabb aabb b2Transform* b2Transform* xf xf CODE: CODE: THIS->ComputeAABB( THIS->ComputeAABB( aabb, aabb, *xf *xf );); %} %} };};

int16 int16 uint16 uint16 int32 int32 uint32 uint32 float32 float32 b2Vec2 b2Vec2 ** b2Mat22 b2Mat22 ** b2World b2World ** b2Body b2Body ** b2BodyDef b2BodyDef ** b2Shape b2Shape ** b2PolygonShape b2PolygonShape ** b2CircleShape b2CircleShape ** b2Filter b2Filter ** b2FixtureDef b2FixtureDef ** b2Fixture b2Fixture ** b2Transform b2Transform ** b2Joint b2Joint ** b2JointDef b2JointDef ** b2DistanceJoint b2DistanceJoint ** b2DistanceJointDef b2DistanceJointDef **

T_IV T_IV T_IV T_IV T_IV T_IV T_IV T_IV T_NV T_NV O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT O_OBJECT

Perl 5 XS

Perl 5 XSpp

C support

yes

no

C++ support

no

yes

Compiler needed

yes

yes

pro

- mature - no runtime penalty

- mature - no runtime penalty

contra

- special - very good C interface file knowledge syntax and a C - compiler compiler needed needed - no C support

?

?

Perl 5 SWIG

/* /* File File :: example.c example.c */ */ double double My_variable My_variable == 3.0 3.0;; /* /* Compute Compute factorial factorial of of nn */ */ int int fact( fact(int int n) n) {{ if if (n (n swig swig -perl5 -perl5 example.i example.i unix unix >> gcc gcc -c -c example.c example.c example_wrap.c example_wrap.c \\ -I/usr/local/lib/perl5/sun4-solaris/5.003/CORE -I/usr/local/lib/perl5/sun4-solaris/5.003/CORE unix unix >> ld ld -G -G example.o example.o example_wrap.o example_wrap.o -o -o example.so example.so unix unix >> # # ^--^--- This This is is for for Solaris Solaris unix unix >> perl5.003 perl5.003 use use example; example; print print example::fact(4), example::fact(4), "\n"; "\n"; print print example::my_mod(23,7), example::my_mod(23,7), "\n"; "\n"; print print $example::My_variable $example::My_variable ++ 4.5, 4.5, "\n"; "\n"; 24 24 22 7.5 7.5

unix unix >> swig swig -python -python example.i example.i unix unix >> gcc gcc -c -c -fpic -fpic example.c example.c example_wrap.c example_wrap.c \\ -I/usr/local/include/python2.0 -I/usr/local/include/python2.0 unix unix >> gcc gcc -shared -shared example.o example.o example_wrap.o example_wrap.o \\ -o -o _example.so _example.so unix unix >> python python Python 2.0 (#6, (#6, Feb Feb 21 21 2001, 2001, 13:29:45) 13:29:45) Python 2.0 [GCC [GCC egcs-2.91.66 egcs-2.91.66 19990314/Linux (egcs-1.1.2 19990314/Linux (egcs-1.1.2 release)] release)] on on linux2 linux2 Type Type "copyright", "copyright", "credits" "credits" or for more more or "license" "license" for information. information. >>> import example example >>> import >>> example.fact(4) >>> example.fact(4) 24 24 >>> example.my_mod(23,7) >>> example.my_mod(23,7) 22 >>> example.cvar.My_variable ++ 4.5 4.5 >>> example.cvar.My_variable 7.5 7.5

unix unix >> swig swig -perl5 -perl5 -module -module example example example.h example.h unix unix >> gcc gcc -c -c example.c example.c example_wrap.c example_wrap.c \\ -I/usr/local/lib/perl5/sun4-solaris/5.003/CORE -I/usr/local/lib/perl5/sun4-solaris/5.003/CORE unix unix >> ld ld -G -G example.o example.o example_wrap.o example_wrap.o -o -o example.so example.so unix unix >> perl5.003 perl5.003 use use example; example; print print example::fact(4), example::fact(4), "\n"; "\n"; print print example::my_mod(23,7), example::my_mod(23,7), "\n"; "\n"; print print $example::My_variable $example::My_variable ++ 4.5, 4.5, "\n"; "\n"; 24 24 22 7.5 7.5

SWIG's C++ support cheatsheet - Full C99 preprocessing. - All ANSI C and C++ datatypes. - Functions, variables, and constants. - Classes. - Single and multiple inheritance. - Overloaded functions and methods. - Overloaded operators. - C++ templates (including member templates, specialization, and partial specialization). - Namespaces. - Variable length arguments. - C++ smart pointers.

Perl 5 XS

Perl 5 XSpp

Perl 5 SWIG

C support

yes

no

yes

C++ support

no

yes

yes

Compiler needed

yes

yes

yes

- mature - no runtime penalty

- mature - no runtime penalty

- C and C++ support - interface file for other languages usable

- very good C knowledge and a C compiler needed

- special interface file syntax - compiler needed - no C support

special interface file syntax or header files needed, compiler needed, edge cases problematic

pro

contra

?

Perl 6 NativeCall

/* /* File File :: example.c example.c */ */ double double My_variable My_variable == 3.0 3.0;; /* /* Compute Compute factorial factorial of of nn */ */ int int fact( fact(int int n) n) {{ if if (n (n exposed exposed as as SDL_BlitSurface SDL_BlitSurface -> -> blit blit or or blit-surface blit-surface SDL_FillRect -> SDL_FillRect -> fill fill or or fill-rect fill-rect xmlC14NDocDumpMemory xmlC14NDocDumpMemory -> -> ??? ???

# -> # Symbol Symbol -> exposed exposed as as SDL_BlitSurface SDL_BlitSurface -> -> blit blit or or blit-surface blit-surface SDL_FillRect -> SDL_FillRect -> fill fill or or fill-rect fill-rect xmlC14NDocDumpMemory xmlC14NDocDumpMemory -> -> ??? ???

use use v6 v6;; use use NativeCall; NativeCall; sub sub fact(int32) fact(int32) returns returns int32 int32 is native('example' 'example')) {{ ** }} is native( say say fact fact 44

int8 int8 int16 int16 int32 int32 int int Int Int num32 num32 num64 num64 num num Str Str OpaquePointer OpaquePointer CArray[Str] CArray[Str]

char char in in C C short short in in C C int int in in C C 3232- or or 64-bit, 64-bit, depends depends what what long long means means locally locally always always 64-bit, 64-bit, long long long long in in C C float float in in C C double double in in C C same same as as num64 num64 C C string string void void ** char char *foo[n] *foo[n]

use use v6 v6;; use use NativeCall; NativeCall; sub sub split(Str, split(Str, int32 int32 $limit $limit == 42) 42) returns returns CArray[Str] CArray[Str] is is native( native('splitter' 'splitter')) {{ ** }} say say split( split('foobar' 'foobar')[ )[33]] # # „b“ „b“

Perl 6 NativeCall -- C C Structures Structures --

/** /** ** xmlNs: xmlNs: ** ** An An XML XML namespace. namespace. ** Note Note that that prefix prefix == == NULL NULL is is valid, valid, it it defines defines the the default default namespace namespace ** within within the the subtree subtree (until (until overridden). overridden). ** ** xmlNsType xmlNsType is is unified unified with with xmlElementType. xmlElementType. */ */ typedef typedef struct struct _xmlNs _xmlNs xmlNs; xmlNs; typedef typedef xmlNs xmlNs *xmlNsPtr; *xmlNsPtr; struct struct _xmlNs _xmlNs {{ struct struct _xmlNs _xmlNs *next; *next; /* /* next next Ns Ns link link for for this this node node */ */ xmlNsType xmlNsType type; type;/* /* global global or or local local */ */ const const xmlChar xmlChar *href; *href; /* /* URL URL for for the the namespace namespace */ */ const const xmlChar xmlChar *prefix; *prefix; /* /* prefix prefix for for the the namespace namespace */ */ void *_private; void *_private; /* /* application application data data */ */ struct /* struct _xmlDoc _xmlDoc *context; *context; /* normally normally an an xmlDoc xmlDoc */ */ };};

typedef typedef struct struct _xmlNs _xmlNs xmlNs; xmlNs; struct struct _xmlNs _xmlNs {{ struct *next; struct _xmlNs _xmlNs *next; /* /* next next Ns Ns link link for for this this node node */ */ xmlNsType type; xmlNsType type; /* /* global global or or local local */ */ const *href; const xmlChar xmlChar *href; /* /* URL URL for for the the namespace namespace */ */ const const xmlChar xmlChar *prefix; *prefix; /* /* prefix prefix for for the the namespace namespace */ */ void *_private; void *_private; /* /* application application data data */ */ struct struct _xmlDoc _xmlDoc *context; *context; /* /* normally normally an an xmlDoc xmlDoc */ */ };};

typedef typedef struct struct _xmlNs _xmlNs xmlNs; xmlNs; struct struct _xmlNs _xmlNs {{ struct *next; struct _xmlNs _xmlNs *next; /* /* next next Ns Ns link link for for this this node node */ */ xmlNsType type; xmlNsType type; /* /* global global or or local local */ */ const *href; const xmlChar xmlChar *href; /* /* URL URL for for the the namespace namespace */ */ const const xmlChar xmlChar *prefix; *prefix; /* /* prefix prefix for for the the namespace namespace */ */ void *_private; void *_private; /* /* application application data data */ */ struct struct _xmlDoc _xmlDoc *context; *context; /* /* normally normally an an xmlDoc xmlDoc */ */ };}; my my class class xmlNs xmlNs is is repr( repr('CStruct' 'CStruct')) {{ has $.next has xmlNs xmlNs $.next;; has $.type has int8 int8 $.type;; has $.uri has Str Str $.uri;; has $.name has Str Str $.name;; has has OpaquePointer OpaquePointer $._private $._private;; has $.context has xmlDoc xmlDoc $.context;; }}

# # next next Ns Ns link link for for this this node node # # global global or or local local # # URL URL for for the the namespace namespace # # prefix prefix for for the the namespace namespace # # application application data data # # normally normally an an xmlDoc xmlDoc

my my class class xmlNs xmlNs is is repr( repr('CStruct' 'CStruct')) {{ has $.next has xmlNs xmlNs $.next;; has $.type has int8 int8 $.type;; has $.uri has Str Str $.uri;; has $.name has Str Str $.name;; has has OpaquePointer OpaquePointer $._private $._private;; has $.context has xmlDoc xmlDoc $.context;; }}

# # next next Ns Ns link link for for this this node node # # global global or or local local # # URL URL for for the the namespace namespace # # prefix prefix for for the the namespace namespace # # application application data data # # normally normally an an xmlDoc xmlDoc

#`( #`( Search Search aa Ns Ns aliasing aliasing aa given given URI. URI. Recurse Recurse on on the the parents parents until until it it finds finds the the defined defined namespace namespace or or return return NULL NULL otherwise. otherwise. )) sub sub xmlSearchNsByHref(xmlDoc, xmlSearchNsByHref(xmlDoc, xmlNode, xmlNode, Str) Str) returns returns xmlNs xmlNs is is native( native('libxml2' 'libxml2')) is is export export {{ ** }}

my my class class xmlNs xmlNs is is repr( repr('CStruct' 'CStruct')) {{ has $.next has xmlNs xmlNs $.next;; has $.type has int8 int8 $.type;; has $.uri has Str Str $.uri;; has $.name has Str Str $.name;; has has OpaquePointer OpaquePointer $._private $._private;; has $.context has xmlDoc xmlDoc $.context;; }}

# # next next Ns Ns link link for for this this node node # # global global or or local local # # URL URL for for the the namespace namespace # # prefix prefix for for the the namespace namespace # # application application data data # # normally normally an an xmlDoc xmlDoc

#`( #`( Search Search aa Ns Ns aliasing aliasing aa given given URI. URI. Recurse Recurse on on the the parents parents until until it it finds finds the the defined defined namespace namespace or or return return NULL NULL otherwise. otherwise. )) sub sub xmlSearchNsByHref(xmlDoc, xmlSearchNsByHref(xmlDoc, xmlNode, xmlNode, Str) Str) returns returns xmlNs xmlNs is is native( native('libxml2' 'libxml2')) is is export export {{ ** }} my my $ns $ns == xmlSearchNsByHref( xmlSearchNsByHref($node $node.doc, .doc, $node $node,, 'foo' 'foo');); say say $ns $ns

my my class class xmlNs xmlNs is is repr( repr('CStruct' 'CStruct')) {{ has $.next has xmlNs xmlNs $.next;; has $.type has int8 int8 $.type;; has $.uri has Str Str $.uri;; has $.name has Str Str $.name;; has has OpaquePointer OpaquePointer $._private $._private;; has $.context has xmlDoc xmlDoc $.context;; }}

# # next next Ns Ns link link for for this this node node # # global global or or local local # # URL URL for for the the namespace namespace # # prefix prefix for for the the namespace namespace # # application application data data # # normally normally an an xmlDoc xmlDoc

#`( #`( Search Search aa Ns Ns aliasing aliasing aa given given URI. URI. Recurse Recurse on on the the parents parents until until it it finds finds the the defined defined namespace namespace or or return return NULL NULL otherwise. otherwise. )) sub sub xmlSearchNsByHref(xmlDoc, xmlSearchNsByHref(xmlDoc, xmlNode, xmlNode, Str) Str) returns returns xmlNs xmlNs is is native( native('libxml2' 'libxml2')) is is export export {{ ** }} my my $ns $ns == xmlSearchNsByHref( xmlSearchNsByHref($node $node.doc, .doc, $node $node,, 'foo' 'foo');); say say $ns $ns # # „(xmlNs)“ „(xmlNs)“

my my class class xmlNs xmlNs is is repr( repr('CStruct' 'CStruct')) {{ has $.next has xmlNs xmlNs $.next;; has $.type has int8 int8 $.type;; has $.uri has Str Str $.uri;; has $.name has Str Str $.name;; has has OpaquePointer OpaquePointer $._private $._private;; has $.context has xmlDoc xmlDoc $.context;; }}

# # next next Ns Ns link link for for this this node node # # global global or or local local # # URL URL for for the the namespace namespace # # prefix prefix for for the the namespace namespace # # application application data data # # normally normally an an xmlDoc xmlDoc

#`( #`( Search Search aa Ns Ns aliasing aliasing aa given given URI. URI. Recurse Recurse on on the the parents parents until until it it finds finds the the defined defined namespace namespace or or return return NULL NULL otherwise. otherwise. )) sub sub xmlSearchNsByHref(xmlDoc, xmlSearchNsByHref(xmlDoc, xmlNode, xmlNode, Str) Str) returns returns xmlNs xmlNs is is native( native('libxml2' 'libxml2')) is is export export {{ ** }} my my $ns $ns == xmlSearchNsByHref( xmlSearchNsByHref($node $node.doc, .doc, $node $node,, 'bar' 'bar');); say say $ns $ns.name .name # # „baz“ „baz“

my my class class xmlNs xmlNs is is repr( repr('CStruct' 'CStruct')) {{ has $.next has xmlNs xmlNs $.next;; has $.type has int8 int8 $.type;; has $.uri has Str Str $.uri;; has $.name has Str Str $.name;; has has OpaquePointer OpaquePointer $._private $._private;; has $.context has xmlDoc xmlDoc $.context;; }}

# # next next Ns Ns link link for for this this node node # # global global or or local local # # URL URL for for the the namespace namespace # # prefix prefix for for the the namespace namespace # # application application data data # # normally normally an an xmlDoc xmlDoc

# # version version string string of of the the document document the the namespace namespace belongs belongs to to say say $ns $ns.context.version .context.version # # „1.0“ „1.0“

/* /* ** A A node-set node-set (an (an unordered unordered collection collection of of nodes nodes without without duplicates). duplicates). */ */ typedef typedef struct struct _xmlNodeSet _xmlNodeSet xmlNodeSet; xmlNodeSet; typedef typedef xmlNodeSet xmlNodeSet *xmlNodeSetPtr; *xmlNodeSetPtr; struct struct _xmlNodeSet _xmlNodeSet {{ int /* int nodeNr; nodeNr; /* number number of of nodes nodes in in the the set set */ */ int /* int nodeMax; nodeMax; /* size size of of the the array array as as allocated allocated */ */ xmlNodePtr xmlNodePtr *nodeTab; *nodeTab; /* /* array array of of nodes nodes in in no no particular particular order order */ */ };};

/* /* ** A A node-set node-set (an (an unordered unordered collection collection of of nodes nodes without without duplicates). duplicates). */ */ typedef typedef struct struct _xmlNodeSet _xmlNodeSet xmlNodeSet; xmlNodeSet; typedef typedef xmlNodeSet xmlNodeSet *xmlNodeSetPtr; *xmlNodeSetPtr; struct struct _xmlNodeSet _xmlNodeSet {{ int /* int nodeNr; nodeNr; /* number number of of nodes nodes in in the the set set */ */ int /* int nodeMax; nodeMax; /* size size of of the the array array as as allocated allocated */ */ xmlNodePtr xmlNodePtr *nodeTab; *nodeTab; /* /* array array of of nodes nodes in in no no particular particular order order */ */ };}; my my class class xmlNodeSet xmlNodeSet is is repr( repr('CStruct' 'CStruct')) {{ has $.nodeNr has int32 int32 $.nodeNr;; # # number number of of nodes nodes in in the the set set has $.nodeMax has int32 int32 $.nodeMax;; # # size size of of the the array array as as allocated allocated has has CArray[xmlNode] CArray[xmlNode] $.nodeTab $.nodeTab;; # # array array of of nodes nodes in in no no particular particular ... ... }}

typedef typedef struct struct _xmlNodeSet _xmlNodeSet xmlNodeSet; xmlNodeSet; typedef typedef xmlNodeSet xmlNodeSet *xmlNodeSetPtr; *xmlNodeSetPtr; struct struct _xmlNodeSet _xmlNodeSet {{ int /* int nodeNr; nodeNr; /* number number of of nodes nodes in in the the set set */ */ int /* int nodeMax; nodeMax; /* size size of of the the array array as as allocated allocated */ */ xmlNodePtr xmlNodePtr *nodeTab; *nodeTab; /* /* array array of of nodes nodes in in no no particular particular order order */ */ };}; my my class class xmlNodeSet xmlNodeSet is is repr( repr('CStruct' 'CStruct')) {{ has $.nodeNr has int32 int32 $.nodeNr;; # # number number of of nodes nodes in in the the set set has $.nodeMax has int32 int32 $.nodeMax;; # # size size of of the the array array as as allocated allocated has has CArray[xmlNode] CArray[xmlNode] $.nodeTab $.nodeTab;; # # array array of of nodes nodes in in no no particular particular ... ... }} for for ^^$set $set.nodeNr .nodeNr -> -> $idx $idx {{ say say $set $set.noteTab[ .noteTab[$idx $idx].value ].value }}

typedef typedef struct struct _xmlNodeSet _xmlNodeSet xmlNodeSet; xmlNodeSet; typedef typedef xmlNodeSet xmlNodeSet *xmlNodeSetPtr; *xmlNodeSetPtr; struct struct _xmlNodeSet _xmlNodeSet {{ int /* int nodeNr; nodeNr; /* number number of of nodes nodes in in the the set set */ */ int /* int nodeMax; nodeMax; /* size size of of the the array array as as allocated allocated */ */ xmlNodePtr xmlNodePtr *nodeTab; *nodeTab; /* /* array array of of nodes nodes in in no no particular particular order order */ */ };}; my my class class xmlNodeSet xmlNodeSet is is repr( repr('CStruct' 'CStruct')) {{ has $.nodeNr has int32 int32 $.nodeNr;; # # number number of of nodes nodes in in the the set set has $.nodeMax has int32 int32 $.nodeMax;; # # size size of of the the array array as as allocated allocated has has CArray[xmlNode] CArray[xmlNode] $.nodeTab $.nodeTab;; # # array array of of nodes nodes in in no no particular particular ... ... }} for for ^^$set $set.nodeNr .nodeNr -> -> $idx $idx {{ say say $set $set.noteTab[ .noteTab[$idx $idx].value ].value }} $set $set.noteTab[^ .noteTab[^$set $set.nodeNr]».value». .nodeNr]».value».say say

Perl 6 NativeCall -- Enumerations Enumerations --

/* /* ** xmlC14NMode: xmlC14NMode: ** ** Predefined Predefined values values for for C14N C14N modes modes ** */ */ typedef typedef enum enum {{ XML_C14N_1_0 == 00,, /* XML_C14N_1_0 /* Origianal Origianal C14N C14N 1.0 1.0 spec spec */ */ XML_C14N_EXCLUSIVE_1_0 XML_C14N_EXCLUSIVE_1_0 == 11,, /* /* Exclusive Exclusive C14N C14N 1.0 1.0 spec spec */ */ XML_C14N_1_1 == 22 /* XML_C14N_1_1 /* C14N C14N 1.1 1.1 spec spec */ */ }} xmlC14NMode; xmlC14NMode;

/* /* ** xmlC14NMode: xmlC14NMode: ** ** Predefined Predefined values values for for C14N C14N modes modes ** */ */ typedef typedef enum enum {{ XML_C14N_1_0 == 00,, /* XML_C14N_1_0 /* Origianal Origianal C14N C14N 1.0 1.0 spec spec */ */ XML_C14N_EXCLUSIVE_1_0 XML_C14N_EXCLUSIVE_1_0 == 11,, /* /* Exclusive Exclusive C14N C14N 1.0 1.0 spec spec */ */ XML_C14N_1_1 == 22 /* XML_C14N_1_1 /* C14N C14N 1.1 1.1 spec spec */ */ }} xmlC14NMode; xmlC14NMode; enum enum xmlC14NMode xmlC14NMode (( XML_C14N_1_0 => XML_C14N_1_0 => 00,, # # Origianal Origianal C14N C14N 1.0 1.0 spec spec XML_C14N_EXCLUSIVE_1_0 XML_C14N_EXCLUSIVE_1_0 => => 11,, # # Exclusive Exclusive C14N C14N 1.0 1.0 spec spec XML_C14N_1_1 => XML_C14N_1_1 => 22,, # # C14N C14N 1.1 1.1 spec spec ););

enum enum xmlC14NMode xmlC14NMode (( XML_C14N_1_0 => XML_C14N_1_0 => 00,, # # Origianal Origianal C14N C14N 1.0 1.0 spec spec XML_C14N_EXCLUSIVE_1_0 XML_C14N_EXCLUSIVE_1_0 => => 11,, # # Exclusive Exclusive C14N C14N 1.0 1.0 spec spec XML_C14N_1_1 => XML_C14N_1_1 => 22,, # # C14N C14N 1.1 1.1 spec spec ););

enum enum xmlC14NMode xmlC14NMode (( XML_C14N_1_0 => XML_C14N_1_0 => 00,, # # Origianal Origianal C14N C14N 1.0 1.0 spec spec XML_C14N_EXCLUSIVE_1_0 XML_C14N_EXCLUSIVE_1_0 => => 11,, # # Exclusive Exclusive C14N C14N 1.0 1.0 spec spec XML_C14N_1_1 => XML_C14N_1_1 => 22,, # # C14N C14N 1.1 1.1 spec spec );); say say +XML_C14N_EXCLUSIVE_1_0 +XML_C14N_EXCLUSIVE_1_0 # # „1“ „1“

enum enum xmlC14NMode xmlC14NMode (( XML_C14N_1_0 => XML_C14N_1_0 => 00,, # # Origianal Origianal C14N C14N 1.0 1.0 spec spec XML_C14N_EXCLUSIVE_1_0 XML_C14N_EXCLUSIVE_1_0 => => 11,, # # Exclusive Exclusive C14N C14N 1.0 1.0 spec spec XML_C14N_1_1 => XML_C14N_1_1 => 22,, # # C14N C14N 1.1 1.1 spec spec );); say say +XML_C14N_EXCLUSIVE_1_0 +XML_C14N_EXCLUSIVE_1_0 # # „1“ „1“ say say xmlC14NMode( xmlC14NMode(11)) # # „XML_C14N_EXCLUSIVE_1_0“ „XML_C14N_EXCLUSIVE_1_0“

enum enum xmlC14NMode xmlC14NMode (( XML_C14N_1_0 => XML_C14N_1_0 => 00,, # # Origianal Origianal C14N C14N 1.0 1.0 spec spec XML_C14N_EXCLUSIVE_1_0 XML_C14N_EXCLUSIVE_1_0 => => 11,, # # Exclusive Exclusive C14N C14N 1.0 1.0 spec spec XML_C14N_1_1 => XML_C14N_1_1 => 22,, # # C14N C14N 1.1 1.1 spec spec );); say say +XML_C14N_EXCLUSIVE_1_0 +XML_C14N_EXCLUSIVE_1_0 # # „1“ „1“ say say xmlC14NMode( xmlC14NMode(11)) # # „XML_C14N_EXCLUSIVE_1_0“ „XML_C14N_EXCLUSIVE_1_0“ say say XML_C14N_EXCLUSIVE_1_0.WHAT XML_C14N_EXCLUSIVE_1_0.WHAT # # „(xmlC14NMode)“ „(xmlC14NMode)“

enum enum xmlC14NMode xmlC14NMode (( XML_C14N_1_0 => XML_C14N_1_0 => 00,, # # Origianal Origianal C14N C14N 1.0 1.0 spec spec XML_C14N_EXCLUSIVE_1_0 XML_C14N_EXCLUSIVE_1_0 => => 11,, # # Exclusive Exclusive C14N C14N 1.0 1.0 spec spec XML_C14N_1_1 => XML_C14N_1_1 => 22,, # # C14N C14N 1.1 1.1 spec spec );); say say +XML_C14N_EXCLUSIVE_1_0 +XML_C14N_EXCLUSIVE_1_0 # # „1“ „1“ say say xmlC14NMode( xmlC14NMode(11)) # # „XML_C14N_EXCLUSIVE_1_0“ „XML_C14N_EXCLUSIVE_1_0“ say say XML_C14N_EXCLUSIVE_1_0.WHAT XML_C14N_EXCLUSIVE_1_0.WHAT # # „(xmlC14NMode)“ „(xmlC14NMode)“ say say XML_C14N_EXCLUSIVE_1_0.perl XML_C14N_EXCLUSIVE_1_0.perl # # “xmlC14NMode::XML_C14N_EXCLUSIVE_1_0“ “xmlC14NMode::XML_C14N_EXCLUSIVE_1_0“

enum enum xmlC14NMode xmlC14NMode (( XML_C14N_1_0 => XML_C14N_1_0 => 00,, # # Origianal Origianal C14N C14N 1.0 1.0 spec spec XML_C14N_EXCLUSIVE_1_0 XML_C14N_EXCLUSIVE_1_0 => => 11,, # # Exclusive Exclusive C14N C14N 1.0 1.0 spec spec XML_C14N_1_1 => XML_C14N_1_1 => 22,, # # C14N C14N 1.1 1.1 spec spec );); say say +XML_C14N_EXCLUSIVE_1_0 +XML_C14N_EXCLUSIVE_1_0 # # „1“ „1“ say say xmlC14NMode( xmlC14NMode(11)) # # „XML_C14N_EXCLUSIVE_1_0“ „XML_C14N_EXCLUSIVE_1_0“ say say XML_C14N_EXCLUSIVE_1_0.WHAT XML_C14N_EXCLUSIVE_1_0.WHAT # # „(xmlC14NMode)“ „(xmlC14NMode)“ say say XML_C14N_EXCLUSIVE_1_0.perl XML_C14N_EXCLUSIVE_1_0.perl # # “xmlC14NMode::XML_C14N_EXCLUSIVE_1_0“ “xmlC14NMode::XML_C14N_EXCLUSIVE_1_0“ sub sub foo(xmlC14NMode foo(xmlC14NMode $mode $mode)) {{ ... ... }}

enum enum xmlC14NMode xmlC14NMode (( XML_C14N_1_0 => XML_C14N_1_0 => 00,, # # Origianal Origianal C14N C14N 1.0 1.0 spec spec XML_C14N_EXCLUSIVE_1_0 XML_C14N_EXCLUSIVE_1_0 => => 11,, # # Exclusive Exclusive C14N C14N 1.0 1.0 spec spec XML_C14N_1_1 => XML_C14N_1_1 => 22,, # # C14N C14N 1.1 1.1 spec spec );); say say +XML_C14N_EXCLUSIVE_1_0 +XML_C14N_EXCLUSIVE_1_0 # # „1“ „1“ say say xmlC14NMode( xmlC14NMode(11)) # # „XML_C14N_EXCLUSIVE_1_0“ „XML_C14N_EXCLUSIVE_1_0“ say say XML_C14N_EXCLUSIVE_1_0.WHAT XML_C14N_EXCLUSIVE_1_0.WHAT # # „(xmlC14NMode)“ „(xmlC14NMode)“ say say XML_C14N_EXCLUSIVE_1_0.perl XML_C14N_EXCLUSIVE_1_0.perl # # “xmlC14NMode::XML_C14N_EXCLUSIVE_1_0“ “xmlC14NMode::XML_C14N_EXCLUSIVE_1_0“ sub sub foo(xmlC14NMode foo(xmlC14NMode $mode $mode)) {{ ... ... }} sub sub foo(xmlC14NMode foo(xmlC14NMode $mode $mode == XML_C14N_1_1 XML_C14N_1_1)) {{ ... ... }}

enum enum xmlC14NMode xmlC14NMode (( XML_C14N_1_0 => XML_C14N_1_0 => 00,, # # Origianal Origianal C14N C14N 1.0 1.0 spec spec XML_C14N_EXCLUSIVE_1_0 XML_C14N_EXCLUSIVE_1_0 => => 11,, # # Exclusive Exclusive C14N C14N 1.0 1.0 spec spec XML_C14N_1_1 => XML_C14N_1_1 => 22,, # # C14N C14N 1.1 1.1 spec spec );); say say ++XML_C14N_EXCLUSIVE_1_0 XML_C14N_EXCLUSIVE_1_0 # # „1“ „1“ say say xmlC14NMode( xmlC14NMode(11)) # # „XML_C14N_EXCLUSIVE_1_0“ „XML_C14N_EXCLUSIVE_1_0“ say say XML_C14N_EXCLUSIVE_1_0.WHAT XML_C14N_EXCLUSIVE_1_0.WHAT # # „(xmlC14NMode)“ „(xmlC14NMode)“ say say XML_C14N_EXCLUSIVE_1_0.perl XML_C14N_EXCLUSIVE_1_0.perl # # “xmlC14NMode::XML_C14N_EXCLUSIVE_1_0“ “xmlC14NMode::XML_C14N_EXCLUSIVE_1_0“ sub sub foo(xmlC14NMode foo(xmlC14NMode $mode $mode)) {{ ... ... }} sub sub foo(xmlC14NMode foo(xmlC14NMode $mode $mode == XML_C14N_1_1 XML_C14N_1_1)) {{ ... ... }} foo(XML_C14N_EXCLUSIVE_1_0) foo(XML_C14N_EXCLUSIVE_1_0) # # does does stuf stuf

Perl 6 NativeCall -- Casting Casting --

struct struct Foo Foo {{ void *theObject; void *theObject; objectType type; objectType type; /* /* enum enum Bar, Bar, Baz, Baz, ... ... */ */ };}; my my class class Foo Foo is is repr( repr('CStruct' 'CStruct')) {{ has has OpaquePointer OpaquePointer $.obj $.obj;; has $.type has int8 int8 $.type;; }} say say $foo $foo.obj; .obj; say say objectType( objectType($foo $foo.obj); .obj);

# # „OpaquePointer“ „OpaquePointer“ # # „Bar“ „Bar“

if if $foo $foo.obj .obj -> -> $o $o {{ my my $bar $bar == nativecast(objectType( nativecast(objectType($o $o),), $o $o);); # # do do something something ... ... }}

Perl 6 NativeCall -- Callbacks Callbacks --

/* /* Register Register aa new new function. function. If If @f @f is is NULL NULL it it unregisters unregisters the the function function */ */ int int xmlXPathRegisterFunc(xmlXPathContextPtr xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, ctxt, const const xmlChar xmlChar ** name, name, xmlXPathFunction xmlXPathFunction f); f); /* /* An An XPath XPath function. function. The The arguments arguments (if (if any) any) are are popped popped out out from from the the ** context context stack stack and and the the result result is is pushed pushed on on the the stack. stack. */ */ void void xmlXPathFunction(xmlXPathParserContextPtr xmlXPathFunction(xmlXPathParserContextPtr ctxt, ctxt, int int nargs); nargs);

/* /* Register Register aa new new function. function. If If @f @f is is NULL NULL it it unregisters unregisters the the function function */ */ int int xmlXPathRegisterFunc(xmlXPathContextPtr xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, ctxt, const const xmlChar xmlChar ** name, name, xmlXPathFunction xmlXPathFunction f); f); /* /* An An XPath XPath function. function. The The arguments arguments (if (if any) any) are are popped popped out out from from the the ** context context stack stack and and the the result result is is pushed pushed on on the the stack. stack. */ */ void void xmlXPathFunction(xmlXPathParserContextPtr xmlXPathFunction(xmlXPathParserContextPtr ctxt, ctxt, int int nargs); nargs); "contains(/foo/bar[1], "contains(/foo/bar[1], 'test 'test 1')" 1')"

/* /* Register Register aa new new function. function. If If @f @f is is NULL NULL it it unregisters unregisters the the function function */ */ int int xmlXPathRegisterFunc(xmlXPathContextPtr xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, ctxt, const const xmlChar xmlChar ** name, name, xmlXPathFunction xmlXPathFunction f); f); /* /* An An XPath XPath function. function. The The arguments arguments (if (if any) any) are are popped popped out out from from the the ** context context stack stack and and the the result result is is pushed pushed on on the the stack. stack. */ */ void void xmlXPathFunction(xmlXPathParserContextPtr xmlXPathFunction(xmlXPathParserContextPtr ctxt, ctxt, int int nargs); nargs); "contains(/foo/bar[1], "contains(/foo/bar[1], 'test 'test 1')" 1')" "messwithit(/foo/bar[1])" "messwithit(/foo/bar[1])"

/* /* Register Register aa new new function. function. If If @f @f is is NULL NULL it it unregisters unregisters the the function function */ */ int int xmlXPathRegisterFunc(xmlXPathContextPtr xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, ctxt, const const xmlChar xmlChar ** name, name, xmlXPathFunction xmlXPathFunction f); f); /* /* An An XPath XPath function. function. The The arguments arguments (if (if any) any) are are popped popped out out from from the the ** context context stack stack and and the the result result is is pushed pushed on on the the stack. stack. */ */ void void xmlXPathFunction(xmlXPathParserContextPtr xmlXPathFunction(xmlXPathParserContextPtr ctxt, ctxt, int int nargs); nargs); "contains(/foo/bar[1], "contains(/foo/bar[1], 'test 'test 1')" 1')" "messwithit(/foo/bar[1])" "messwithit(/foo/bar[1])" sub sub xmlXPathRegisterFunc(xmlXPathContext, xmlXPathRegisterFunc(xmlXPathContext, ?) ?) is is native('libxml2') native('libxml2') {{ ** }}

/* /* Register Register aa new new function. function. If If @f @f is is NULL NULL it it unregisters unregisters the the function function */ */ int int xmlXPathRegisterFunc(xmlXPathContextPtr xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, ctxt, const const xmlChar xmlChar ** name, name, xmlXPathFunction xmlXPathFunction f); f); /* /* An An XPath XPath function. function. The The arguments arguments (if (if any) any) are are popped popped out out from from the the ** context context stack stack and and the the result result is is pushed pushed on on the the stack. stack. */ */ void void xmlXPathFunction(xmlXPathParserContextPtr xmlXPathFunction(xmlXPathParserContextPtr ctxt, ctxt, int int nargs); nargs); "contains(/foo/bar[1], "contains(/foo/bar[1], 'test 'test 1')" 1')" "messwithit(/foo/bar[1])" "messwithit(/foo/bar[1])" sub sub xmlXPathRegisterFunc(xmlXPathContext, xmlXPathRegisterFunc(xmlXPathContext, &custom-xpath-func &custom-xpath-func (xmlXPathContext, (xmlXPathContext, int32) int32) )) is is native('libxml2') native('libxml2') {{ ** }}

/* /* Register Register aa new new function. function. If If @f @f is is NULL NULL it it unregisters unregisters the the function function */ */ int int xmlXPathRegisterFunc(xmlXPathContextPtr xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, ctxt, const const xmlChar xmlChar ** name, name, xmlXPathFunction xmlXPathFunction f); f); /* /* An An XPath XPath function. function. The The arguments arguments (if (if any) any) are are popped popped out out from from the the ** context context stack stack and and the the result result is is pushed pushed on on the the stack. stack. */ */ void void xmlXPathFunction(xmlXPathParserContextPtr xmlXPathFunction(xmlXPathParserContextPtr ctxt, ctxt, int int nargs); nargs); "contains(/foo/bar[1], "contains(/foo/bar[1], 'test 'test 1')" 1')" "messwithit(/foo/bar[1])" "messwithit(/foo/bar[1])" sub sub xmlXPathRegisterFunc(xmlXPathContext, xmlXPathRegisterFunc(xmlXPathContext, &custom-xpath-func &custom-xpath-func (xmlXPathContext, (xmlXPathContext, int32) int32) )) is is native('libxml2') native('libxml2') {{ ** }} sub sub messwithit(xmlXPathContext messwithit(xmlXPathContext $ctxt $ctxt,, int32 int32 $nargs $nargs)) {{ #`( #`( stuf stuf )) }}

/* /* Register Register aa new new function. function. If If @f @f is is NULL NULL it it unregisters unregisters the the function function */ */ int int xmlXPathRegisterFunc(xmlXPathContextPtr xmlXPathRegisterFunc(xmlXPathContextPtr ctxt, ctxt, const const xmlChar xmlChar ** name, name, xmlXPathFunction xmlXPathFunction f); f); /* /* An An XPath XPath function. function. The The arguments arguments (if (if any) any) are are popped popped out out from from the the ** context context stack stack and and the the result result is is pushed pushed on on the the stack. stack. */ */ void void xmlXPathFunction(xmlXPathParserContextPtr xmlXPathFunction(xmlXPathParserContextPtr ctxt, ctxt, int int nargs); nargs); "contains(/foo/bar[1], "contains(/foo/bar[1], 'test 'test 1')" 1')" "messwithit(/foo/bar[1])" "messwithit(/foo/bar[1])" sub sub xmlXPathRegisterFunc(xmlXPathContext, xmlXPathRegisterFunc(xmlXPathContext, &custom-xpath-func &custom-xpath-func (xmlXPathContext, (xmlXPathContext, int32) int32) )) is is native('libxml2') native('libxml2') {{ ** }} sub sub messwithit(xmlXPathContext messwithit(xmlXPathContext $ctxt $ctxt,, int32 int32 $nargs $nargs)) {{ #`( #`( stuf stuf )) }} xmlXPathRegisterFunc( xmlXPathRegisterFunc($ctxt $ctxt,, &messwithit &messwithit););

perl6 perl6 -MXML::LibXML -MXML::LibXML -e -e 'say 'say parse-xml parse-xml ""' ""'

perl6 perl6 -MXML::LibXML -MXML::LibXML -e -e 'say 'say parse-xml parse-xml ""' ""' === ===SORRY! SORRY!=== === Error Error while while parsing parsing XML XML document document XML::LibXML::Parser XML::LibXML::Parser error: error: Extra Extra content content at at the the end end of of the the document document < /foo> in in method method gist gist at at src/gen/m-CORE.setting:14570 src/gen/m-CORE.setting:14570 in in sub sub say say at at src/gen/m-CORE.setting:17327 src/gen/m-CORE.setting:17327 in in block block at at -e:1 -e:1

Perl 6 NativeCall

-- Conformance Conformance vs. vs. Usability Usability --

$xml_doc $xml_doc->documentElement ->documentElement -> ->firstChild firstChild ->toStringC14N( ->toStringC14N(11))

$xml-doc $xml-doc..documentElement\ documentElement\ .firstChild\ .firstChild\ .toStringC14N( .toStringC14N(:comments :comments))

$xml-doc $xml-doc..document-element\ document-element\ .first-child\ .first-child\ .c14n( .c14n(:comments :comments))

$xml-doc $xml-doc..document-element[ document-element[00]] .c14n( .c14n(:comments :comments))

A Rant

Function: Function: xmlXPathNewString xmlXPathNewString xmlXPathObjectPtr xmlXPathObjectPtr xmlXPathNewString xmlXPathNewString ((const const xmlChar xmlChar ** val) val) Create Create aa new new xmlXPathObjectPtr xmlXPathObjectPtr of of type type string string and and of of value value @val @val val: the val: the xmlChar xmlChar ** value value Returns: Returns: the the newly newly created created object. object.

Perl 5 XS

Perl 5 XSpp

Perl 5 SWIG

Perl 6 NativeCall

C support

yes

no

yes

yes

C++ support

no

yes

yes

no

Compiler needed

yes

yes

yes

no

pro

- mature - no runtime penalty

- mature - no runtime penalty

- C and C++ support - interface file for other languages usable

- no compiler, and only a little C knowledge needed - C headers not needed

contra

- special special interface - very good C interface file file syntax or knowledge syntax header files and a C - compiler needed, compiler compiler needed needed, edge needed - no C cases problematic support

- no C++ support

FROGGS freenode/#perl6 [email protected] github.com/FROGGS

-- simple simple example example -- the the is native trait trait is native -- the the empty body empty body -- the the is symbol trait is symbol trait -- the the signature signature -- type type mapping mapping -- callbacks callbacks -- the the returns returns trait trait -- cglobal cglobal -- nativecast nativecast -- comparision comparision -- works works on JVM and and MoarVM MoarVM on Parrot, Parrot, JVM -- enums enums -- is is encoded('utf8') encoded('utf8')