我正在编写我的第一个XS模块(只是C数学库的包装器),并且成功了。最大的问题是文档很难理解和/或不完整。
我已经在XS中成功编写了一个构造函数,并将一些函数作为方法调用从库中实现。这很好。
现在我也想实现一个程序界面。出于这个原因,我需要知道它是否是一个方法调用。如果它的一个方法调用用函数计算的数字存储在实例中,如果它是对函数的过程调用,则将其作为第一个参数给出。 这是余弦函数的当前代码:
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
答案 0 :(得分:4)
一般来说,编写想要被称为方法或函数的subs是一个坏主意。有一个或两个众所周知的模块可以做到这一点(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);
答案 1 :(得分:0)
在我的情况下,这是一个简单的问题,我根本没有看到它。在if-else语句中声明SV * zahl是个问题。在if之前的预先声明是解决方案的关键。
但我同意tobyinks模块的解决方案,这些模块可供其他人使用或在某处发布。