2010-11-15 15 views
15

Este problema es tan simple que puedo sentir que viene el RTFM. Sin embargo, he estado buscando en los documentos (Inline, Inline-C, Inline-C-Cookbook) toda la mañana y no puedo encontrar la manera de resolver este problema.Perl: ¿cómo puedo poner todo mi código en línea C en un archivo separado?

Quiero usar C en línea, pero no quiero tener código C en el mismo archivo que mi código perl.

(A Emacs no le gusta tener dos idiomas en un archivo. En principio esto es una cuestión de conveniencia, pero en la práctica tengo que editar mi C en un archivo y luego copiarlo y pegarlo en mi script de Perl.) perl

Aquí está trabajando:

#!/usr/bin/perl 

use Inline C => DATA; 
use strict; 
use warnings; 
use List::Util qw(sum); 
use feature qw(say); 

my @array = (1..10); 
say "native perl: ", sum(@array), ", Inline C: ", sum1(\@array); 

__END__ 
__C__ 

double sum1(AV* array) { 
    int i; 
    double sum = 0.0; 
    for (i=0; i<=av_len(array); i++) { 
    SV** elem = av_fetch(array, i, 0); 
    if (elem != NULL) 
     sum += SvNV(*elem); 
    } 
    return sum; 
} 

(gracias a mobrule por sacarme este momento)

quiero mover todo el código C (o tanto como sea posible) en una. archivo de encabezado separado.

Lo que puedo hacer es poner sum1 en una cabecera, y hacer esto:

# same perl as above except now say sum2 instead of sum1 
__END__ 
__C__ 
#include "sum.h" 

double sum2(AV* array) { 
    sum1(array); 
} 

Esto es lo suficientemente buena como la que ya no tengo que editar el C en Perl-mode, pero me pregunto si hay ISN ¿Es una solución más elegante a este problema?

+0

Eso se ve muy elegante. –

+0

@Pedro Silva ojo del espectador y todo eso. solo me parece un poco redundante. – flies

Respuesta

21

Usted puede poner su código C en un archivo separado y utilizar Inline::bind para cargarlo en tiempo de ejecución

use Inline; 
use File::Slurp; 

my $data = read_file('source.c'); 
Inline->bind(C => $data); 

o cargar el código fuente en un bloque BEGIN {} para obligar a éste en tiempo de compilación

my $data; 
use File::Slurp; 
BEGIN { 
    $data = read_file('source.c'); 
} 
use Inline C => $data; 
+1

gracias! Me sorprendió descubrir que esta solución no se vuelve a compilar en cada ejecución. ¡Inline es inteligente! – flies

2

Al menos con las versiones recientes de Inline, puede simplemente especificar un nombre de archivo en lugar de una cadena al usar In-line:

use Inline C => "./test.c"; 

La advertencia aquí es que Inline :: C usa un enfoque simple de expresiones regulares para determinar si su argumento "se parece" a un nombre de archivo, por lo que la parte "./" es importante. También es una buena idea iniciar su archivo C con una directiva #line 1 test.c, por lo que el depurador C lo sabrá.

Cuestiones relacionadas