我已经编程了一段时间。现在我需要编写一个perl可以调用的C程序。 它应该具有与以下伪perl函数相同的语法:取两个输入,两个都是字符串(可能包含二进制字符,甚至是“\ x00”),输出一个新字符串。
当然,函数的算法会更复杂,这就是我需要在C中执行的原因。
sub dummy {
my ($a, $b) = @_;
return $a . $b;
}
我简要介绍了SWIG的实现,但是输入/输出不是一个整数并不容易,希望有人能给出一个具体的例子。
提前致谢。
更新:从Rob(cpan中的Inline :: C模块的作者)中得到了一个很好的例子,谢谢!
##############################
use warnings;
use strict;
use Devel::Peek;
use Inline C => Config =>
BUILD_NOISY => 1,
;
use Inline C => <<'EOC';
SV * foo(SV * in) {
SV * ret;
STRLEN len;
char *tmp = SvPV(in, len);
ret = newSVpv(tmp, len);
sv_catpvn(ret, tmp, len);
return ret;
}
EOC
my $in = 'hello' . "\x00" . 'world';
my $ret = foo($in);
Dump($in);
print "\n";
Dump ($ret);
##############################
答案 0 :(得分:11)
对于这种事情,Perl有一种名为XS的粘合语言。它知道Perl数据类型和C类型之间的映射。例如,C函数
char *dummy(char *a, int len_a, char *b, int len_b);
可以用XS代码
包装MODULE = Foo PACKAGE = Foo
char *
dummy(char *a, int length(a), char *b, int length(b));
安装模块时将编译Foo.xs
文件,所有相关的构建工具链都支持XS。
将自动生成参数转换代码,以便在从Perl加载XS代码后,可以在Perl中调用该函数Foo::dummy("foo", "bar")
:
package Foo;
use parent 'DynaLoader';
Foo->bootstrap;
perl文档中有XS tutorial,perlxs
中有参考文档。
XS是模块的不错选择,但对于一次性脚本来说却很尴尬。 Inline::C
模块允许您将胶水C代码直接嵌入到Perl脚本中,并在C代码更改时自动编译。但是,使用这种方法可以自动生成更少的代码。