2010-11-15 3 views
15

Эта проблема настолько проста, что я чувствую приближение RTFM. Тем не менее, я смотрел на документы (Inline, Inline-C, Inline-C-Cookbook) все утро, и я не могу понять, как решить эту проблему.Perl: как я могу поместить весь мой встроенный код C в отдельный файл?

Я хочу использовать встроенный C, но я не хочу иметь код C в том же файле, что и мой perl-код.

(Emacs не любит иметь два языка в одном файле. В принципе, это вопрос удобства, но на практике мне нужно редактировать свой C в одном файле, а затем скопировать его в свой скрипт perl.)

Здесь работает Perl:

#!/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; 
} 

(благодаря mobrule для получения меня это далеко)

Я хочу, чтобы переместить весь код C (или как можно больше) в. отдельный файл заголовка.

Что я могу сделать, это положить sum1 в заголовок, и сделать это:

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

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

Это достаточно хорошо, как я больше не придется редактировать C в жемчужно-режиме, но мне интересно, если есть ISN Более элегантное решение этой проблемы?

+0

Это выглядит довольно элегантно. –

+0

@ Педро Сильва глаз смотрящего и все такое. просто кажется немного лишним для меня. – flies

ответ

21

Вы можете поместить свой код C в отдельном файле и использовать Inline::bind, чтобы загрузить его во время выполнения

use Inline; 
use File::Slurp; 

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

или загрузки исходного кода в BEGIN {} блоке, чтобы связать его во время компиляции

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

спасибо! Я с удивлением обнаружил, что это решение не перекомпилируется при каждом исполнении. Встроенный умный! – flies

2

По крайней мере, с недавними версиями Inline вы можете просто указать имя файла вместо строки при использовании Inline:

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

Предостережение здесь заключается в том, что Inline :: C использует простой подход в регулярном выражении, чтобы определить, является ли его аргумент «похожим» на имя файла, поэтому важна часть «./». Также неплохо запустить свой файл C с помощью директивы #line 1 test.c, поэтому отладчик C узнает об этом.

Смежные вопросы