ST(0) denota al primero,
ST(1) al segundo, etc. Esto es: ST(i) es equivalente a $_[$i].
El siguiente ejemplo provee una función sum que devuelve 
la suma de sus argumentos. Creamos la estructura de
ficheros y directorios con h2xs -A -n Sum.
Después de añadir el directorio script y el programa de
prueba usesum.pl la estructura queda como sigue:
lhp@nereida:~/Lperl/src/XSUB/Sum$ tree
.
|-- Changes
|-- MANIFEST
|-- Makefile.PL
|-- README
|-- Sum.xs
|-- lib
|   `-- Sum.pm
|-- ppport.h
|-- script
|   `-- usesum.pl
`-- t
    `-- Sum.t
El programa de prueba ilustra el modo de uso:
lhp@nereida:~/Lperl/src/XSUB/Sum/script$ cat -n usesum.pl 1 #!/usr/bin/perl -w 2 use strict; 3 use blib; 4 use Sum; 5 6 die "Supply numbers\n" unless @ARGV; 7 my $s = sum(@ARGV); 8 print "$s\n";En la ejecución que sigue nótese el control de tipos cuando la entrada es ilegal:
lhp@nereida:~/Lperl/src/XSUB/Sum/script$ usesum.pl 2 3 5 10 lhp@nereida:~/Lperl/src/XSUB/Sum/script$ usesum.pl 2 3 a 4 Argument "a" isn't numeric in subroutine entry at ./usesum.pl line 7. 9 lhp@nereida:~/Lperl/src/XSUB/Sum/script$ usesum.pl 2.5 3.4 2.1 8 lhp@nereida:~/Lperl/src/XSUB/Sum/script$
A continuación pasamos a comentar los contenidos de Sum.xs:
lhp@nereida:~/Lperl/src/XSUB/Sum$ cat -n Sum.xs
 1  #include "EXTERN.h"
 2  #include "perl.h"
 3  #include "XSUB.h"
 4
 5  #include "ppport.h"
 6
 7
 8  #ifdef SVf_IVisUV
 9  #  define slu_sv_value(sv) \
         (SvIOK(sv)) ? \
              (SvIOK_UV(sv)) ? (NV)(SvUVX(sv)) : (NV)(SvIVX(sv))\ 
            : (SvNV(sv))
10  #else
11  #  define slu_sv_value(sv) (SvIOK(sv)) ? (NV)(SvIVX(sv)) : (SvNV(sv))
12  #endif
13
14
15  MODULE = Sum            PACKAGE = Sum
16
17  NV
18  sum(...)
19  PROTOTYPE: @
20  CODE:
21  {
22      SV *sv;
23      int index;
24      if(!items) {
25          XSRETURN_UNDEF;
26      }
27      sv = ST(0);
28      RETVAL = slu_sv_value(sv);
29      for(index = 1 ; index < items ; index++) {
30          sv = ST(index);
31          RETVAL += slu_sv_value(sv);
32      }
33  }
34  OUTPUT:
35      RETVAL
sum (línea 17).
Otros tipos posibles son: IV por Integer Value, 
PV para las cadenas (Pointer Value).
xsubpp que debe generar 
un prototipo para la interface Perl a la subrutina.
sv como puntero a un tipo escalar SV (por
Scalar Value). El tipo  SV  es el tipo C usado por Perl para representar
las variables Perl de tipo escalar.
Analogamente los tipos  AV  y  HV  son las representaciones C de 
los tipos Perl Array Value y Hash Value.
@_.
return undef.
ST(0) es el primero,
ST(1) el segundo, etc. Esto es: ST(i) es equivalente a $_[$i].
RETVAL casa con el tipo de retorno declarado para la función.
Por defecto la función C generada usará RETVAL para guardar el 
valor de retorno. En los casos sencillos el valor de RETVAL
será colocado en ST(0) para que sea recibido por Perl como
el valor retornado por la XSUB.
Sin embargo, cuando hay una sección CODE: como en este ejemplo,
el valor en RETVAL no es devuelto automáticamente y es necesario 
explicitarlo en una sección OUTPUT:.
xsubpp la XSUB sum es traducida asi:
lhp@nereida:~/Lperl/src/XSUB/Sum$ sed -ne '27,51p' Sum.c
XS(XS_Sum_sum)
{
    dXSARGS;
    {
        NV      RETVAL;
        dXSTARG;
#line 21 "Sum.xs"
{
    SV *sv;
    int index;
    if(!items) {
        XSRETURN_UNDEF;
    }
    sv = ST(0);
    RETVAL = slu_sv_value(sv);
    for(index = 1 ; index < items ; index++) {
        sv = ST(index);
        RETVAL += slu_sv_value(sv);
    }
}
#line 48 "Sum.c"
        XSprePUSH; PUSHn((NV)RETVAL);
    }
    XSRETURN(1);
}
Casiano Rodríguez León
