使用NativeCall将C库函数合并到Perl6中

con*_*con 3 perl6 nativecall

我试图在Perl6中使用lgammaC语言math.h.

我如何将其融入Perl6?

我试过了

use NativeCall;

sub lgamma(num64 --> num64) is native(Str) {};

say lgamma(3e0);

my $x = 3.14;
say lgamma($x);
Run Code Online (Sandbox Code Playgroud)

这适用于第一个数字(a Str)但第二个数字失败$x,给出错误:

This type cannot unbox to a native number: P6opaque, Rat
  in block <unit> at pvalue.p6 line 8
Run Code Online (Sandbox Code Playgroud)

我想这样做非常简单,就像在Perl5中那样:use POSIX 'lgamma';然后lgamma($x)我不知道如何在Perl6中做到这一点.

Bra*_*ert 6

原生值的错误并不总是很清楚.

基本上它是说老鼠不是一个数字.

3.14是一只老鼠.(合理的)

say 3.14.^name; # Rat
say 3.14.nude.join('/'); # 157/50
Run Code Online (Sandbox Code Playgroud)

每次调用它时,你总是可以将值强制为Num.

lgamma( $x.Num )
Run Code Online (Sandbox Code Playgroud)

这似乎并不那么好.


我只是将原生子包裹在另一个中,将所有实数转换为Num.
(Real是除Complex之外的所有数字)

sub lgamma ( Num(Real) \n --> Num ){
  use NativeCall;
  sub lgamma (num64 --> num64) is native {}

  lgamma( n )
}

say lgamma(3);    # 0.6931471805599453
say lgamma(3.14); # 0.8261387047770286
Run Code Online (Sandbox Code Playgroud)

  • @con这是你如何在没有sigil(`$ @%`)的情况下声明一个"变量".在签名中,它有点像将它声明为`raw`` :( \n)``:( $ n是raw)`.我主要在这里使用它,因为代码很短,并且不需要用`$`来声明它的保护. (2认同)

jjm*_*elo 5

$x没有类型.如果您使用任何类型,比方num64说它会说:

Cannot assign a literal of type Rat (3.14) to a native variable of type num. You can declare the variable to be of type Real, or try to coerce the value with 3.14.Num or Num(3.14)
Run Code Online (Sandbox Code Playgroud)

所以你这样做:

my  num64 $x = 3.14.Num;
Run Code Online (Sandbox Code Playgroud)

这会将数字精确转换为所需的表示形式 lgamma