Perl: как я могу поместить весь мой встроенный код C в отдельный файл?
Эта проблема настолько проста, что я чувствую, что RTFM придет. Тем не менее, я смотрел документы (Inline, Inline-C, Inline-C-Cookbook) все утро, и я не могу понять, как решить эту проблему.
Я хочу использовать inline C, но я не хочу иметь код C в том же файле, что и мой perl-код.
(Emacs не любит иметь два языка в одном файле. В принципе, это вопрос удобства, но на практике мне приходится редактировать свой C в одном файле, а затем скопировать его в свой perl script.)
Здесь работает 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-режиме, но мне интересно, нет ли более элегантного решения этой проблемы?
Ответы
Ответ 1
Вы можете поместить свой 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;
Ответ 2
По крайней мере, с недавними версиями Inline вы можете просто указать имя файла вместо строки при использовании Inline:
use Inline C => "./test.c";
Здесь предостережение заключается в том, что Inline:: C использует простой метод regexp для определения того, является ли его аргумент "похожим" на имя файла, поэтому важна часть "./". Также неплохо начать свой файл C с директивой #line 1 test.c
, поэтому отладчик C узнает об этом.