Perl: как я могу поместить весь свой встроенный код C в отдельный файл? - PullRequest
17 голосов
/ 15 ноября 2010

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

Я хочу использовать встроенный 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 в perl-mode,но мне интересно, если нет более элегантного решения этой проблемы?

Ответы [ 2 ]

22 голосов
/ 15 ноября 2010

Вы можете поместить свой код 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;
3 голосов
/ 20 ноября 2013

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

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

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

...