Perl:如何将所有内联C代码放到一个单独的文件中?

时间:2022-11-22 21:33:27

This problem is so simple I can feel the RTFM's coming. However, I've been looking at the docs (Inline, Inline-C, Inline-C-Cookbook ) all morning and I can't figure out how to solve this problem.

这个问题很简单,我能感觉到RTFM的到来。然而,我整个上午都在看文档(内联的、内联的、内联的),我不知道如何解决这个问题。

I want to use inline C, but I don't want to have C code in the same file as my perl code.

我希望使用内联C,但不希望将C代码放在与perl代码相同的文件中。

(Emacs doesn't like having two languages in one file. In principle this is a matter of convenience, but in practice I'm having to edit my C in one file then copy-paste it into my perl script.)

(Emacs不喜欢在一个文件中包含两种语言。原则上,这是一个方便的问题,但实际上,我必须在一个文件中编辑C,然后复制粘贴到perl脚本中。

Here is working 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;
}

(thanks to mobrule for getting me this far.)

(多亏了mobrule,让我走了这么远。)

I want to move all of the C code (or as much as possible) into a separate header file.

我希望将所有C代码(或尽可能多地)移动到一个单独的头文件中。

What I can do is put sum1 into a header, and do this:

我能做的就是把sum1放到header中,这样做:

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

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

This is good enough as I no longer have to edit the C in perl-mode, but I wonder if there isn't a more elegant solution to this problem?

这已经足够了,因为我不再需要在perl模式下编辑C,但是我想知道是否有更好的解决方案可以解决这个问题?

2 个解决方案

#1


22  

You can put your C code in a separate file and use Inline::bind to load it at runtime

您可以将C代码放在一个单独的文件中,并使用Inline:::bind以在运行时加载它

use Inline;
use File::Slurp;

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

or loading the source code in a BEGIN {} block to bind it at compile time

或者,在编译时将源代码装入一个BEGIN{}块来绑定它。

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

#2


2  

At least with recent versions of Inline, you can simply specify a file name instead of a string when use-ing Inline:

至少在最近的内联版本中,当使用内联时,您可以简单地指定文件名而不是字符串:

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

The caveat here is that Inline::C uses a simple regexp approach to determining whether its argument "looks like" a filename, which is why the "./" part is important. It's also a good idea to start your C file with a #line 1 test.c directive, so the C debugger will know about it.

这里需要注意的是,Inline:::C使用了一个简单的regexp方法来确定其参数“是否像”一个文件名,这就是为什么“。/”是很重要的一部分。使用#line 1测试来启动C文件也是一个好主意。c指令,所以c调试器会知道。

#1


22  

You can put your C code in a separate file and use Inline::bind to load it at runtime

您可以将C代码放在一个单独的文件中,并使用Inline:::bind以在运行时加载它

use Inline;
use File::Slurp;

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

or loading the source code in a BEGIN {} block to bind it at compile time

或者,在编译时将源代码装入一个BEGIN{}块来绑定它。

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

#2


2  

At least with recent versions of Inline, you can simply specify a file name instead of a string when use-ing Inline:

至少在最近的内联版本中,当使用内联时,您可以简单地指定文件名而不是字符串:

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

The caveat here is that Inline::C uses a simple regexp approach to determining whether its argument "looks like" a filename, which is why the "./" part is important. It's also a good idea to start your C file with a #line 1 test.c directive, so the C debugger will know about it.

这里需要注意的是,Inline:::C使用了一个简单的regexp方法来确定其参数“是否像”一个文件名,这就是为什么“。/”是很重要的一部分。使用#line 1测试来启动C文件也是一个好主意。c指令,所以c调试器会知道。