目前,我正在编写我的第一个XS模块(只是C数学库的包装器),取得了很好的成功。最大的问题是很难理解和/或不完整的文档。
我已经成功地用XS编写了一个构造函数,并以方法调用的形式实现了库外的一些函数。效果很好。
现在,我也想实现一个过程接口。因此,我需要知道它是否是一个方法调用。如果它的a方法调用要与函数一起计算的数字存储在实例中,如果它是对函数的过程调用--它是作为第一个参数给出的数字。这是余弦函数的当前代码:
double
cos(...)
CODE:
SV *arg = newSVsv(ST(0));
if (sv_isobject(arg)) {
HV *self_hv = MUTABLE_HV(SvRV(arg));
SV **callback_ptr = hv_fetchs(self_hv, "Number", 0);
SV *zahl = *callback_ptr;
}
else {
SV *zahl = newSVnv(arg);
}
double x = SvNV(zahl);
RETVAL = cos(x);
OUTPUT:
RETVAL发布于 2014-10-23 12:03:44
一般说来,编写被称为方法或函数的子程序是个坏主意。有一两个众所周知的模块可以做到这一点(CGI.pm弹簧),但在大多数情况下,这对最终用户来说是令人困惑的,并且不必要地使您自己的代码复杂化。没人会为此感谢你的。选择一种风格并坚持下去。
让我们假设您选择了坚持OO编程。然后,一旦您的模块工作和测试,您可以编写第二个模块,提供可导出的功能,而不是OO接口。第二个模块可能可以用普通的旧Perl编写,只是充当OO模块的包装器。
例如,使用纯Perl (而不是XS)来实现可读性:
use v5.14;
package MyStuff::Maths::OO {
use Class::Tiny qw(number);
sub cosine {
my $self = shift;
my $number = $self->number;
...;
return $cosine;
}
}
package MyStuff::Maths::Functional {
use Exporter::Shiny qw(cosine);
sub cosine {
my $obj = ref($_[0]) ? $_[0] : MyStuff::Maths::OO->new(number => $_[0]);
return $obj->cosine;
}
}现在,最终用户可以选择像这样使用OO界面:
use v5.14;
use MyStuff::Maths::OO;
my $obj = MyStuff::Maths::OO->new(number => 0.5);
say $obj->cosine;或者使用功能接口:
use v5.14;
use MyStuff::Maths::Functional -all;
say cosine(0.5);发布于 2014-10-24 05:57:04
在我的例子中,这是一个简单的问题,我根本没有看到它。如果-否则-语句中的SV *zahl声明是问题所在。if之前的预声明是解决方案的关键。
但我同意由其他人使用或在某个地方发布的模块的tobyinks解决方案。
https://stackoverflow.com/questions/26523591
复制相似问题