Breve Introducción a Inline

El módulo Inline proporciona los medios para realizar las pasarelas entre el lenguaje Perl y otro lenguaje de programación. En particular Inline provee una capa por encima de XS que facilita la integración entre código C y código Perl. Una buena fuente de ejemplos es el texto Pathollogically Polluting perl with C, Python and Other Rubbish using Inline.pm del propio autor del módulo, Brian Ingerson [6]). Veamos un ejemplo usando Inline::C:
lhp@nereida:~/Lperl/src/inline$ cat -n pi.pl
 1  #!/usr/bin/perl -w
 2  use strict;
 3  use List::Util qw(sum);
 4  use Inline 'C';
 5
 6  my $p = shift || 4;
 7  my $n = shift || 10000;
 8  my $pi = sum(map { computepi($_, $n, $p) } 0..$p-1);
 9  print "Pi es: 3.14159265358979 ...\nValor calculado: $pi\n";
10
11  __END__
12  __C__
13
14  double computepi(int id, int N, int np) {
15    double sum, left;
16
17    int i;
18    for(i=id, sum = 0; i<N; i+=np) {
19      double x = (i + 0.5)/N;
20      sum += 4 / (1 + x*x);
21    }
22    sum /= N;
23    return (sum);
24  }
El código C puede almacenarse dentro del fichero DATA (esto es, a partir de la aparición del marcador __END__ en una sección determinada por el marcador __C__. También puede guardarse en una cadena ordinaria que es pasada a Inline:
lhp@nereida:~/Lperl/src/inline$ cat -n hello.pl
     1  #!/usr/local/bin/perl -w
     2  use strict;
     3  use Inline C => <<'END_C';
     4  void greet() {
     5    printf("Hello, world\n");
     6  }
     7  END_C
     8
     9  greet;
Ejecutémos dos veces el ejemplo del cálculo de $ \pi $ y cronometremos los tiempos de ejecución:
lhp@nereida:~/Lperl/src/inline$ time pi.pl
Pi es: 3.14159265358979 ...
Valor calculado: 3.14159265442313

real    0m1.773s
user    0m1.430s
sys     0m0.270s
lhp@nereida:~/Lperl/src/inline$ time pi.pl
Pi es: 3.14159265358979 ...
Valor calculado: 3.14159265442313

real    0m0.066s
user    0m0.060s
sys     0m0.010s
Vemos que la segunda vez tarda menos que la primera. Esto es así porque la primera vez Inline genera una librería que - por defecto - se guarda en el subdirectorio __Inline:
lhp@nereida:~/Lperl/src/inline$ ls -ltr | tail -1
drwxr-xr-x  4 lhp lhp 4096 2007-02-20 10:39 _Inline
lhp@nereida:~/Lperl/src/inline$ tree _Inline/
_Inline/
|-- build
|-- config
`-- lib
    `-- auto
        `-- pi_pl_fa9f
            |-- pi_pl_fa9f.bs
            |-- pi_pl_fa9f.inl
            `-- pi_pl_fa9f.so

4 directories, 4 files

La gramática de Inline para C reconoce ciertas definiciones de funciones del código C. Esto es, Inline generará el código necesario para enlazar la llamada a la función como si fuera una subrutina Perl. Si no puede reconocer la definición, esta será ignorada sin que hayan mensajes de error o advertencia. No quedará disponible en el ámbito de Perl, pero podrá aún seguir siendo usada en el ámbito de C. Inline busca por definiciones de funciones de estilo:

tipo_de_retorno nombre_de_funcion ( pares_tipo_identificador ) { cuerpo }

en las parejas tipo identificador, ... puede usarse cualquier tipo que esté definido en el fichero typemap (véase sección 17.19).

Las siguientes definiciones no serán reconocidas:

Foo(int i) # no hay tipo de retorno
int foo(float f) { # no existe definición en typemap para float
int Foo(num) double num; { # la vieja sintáxis C no se soporta
void Foo(void) { # void se permite solo para el retorno

Casiano Rodríguez León
2012-02-29