使用NativeCall为Windows和Linux发布用于C库的Perl 6绑定的最佳策略是什么?
开发人员是否需要编译.dll和.so文件并将它们与perl6代码一起上传到github?或者perl6上有一个选项,比如perl5可以将C源文件与Perl 6代码捆绑在一起,C编译器将作为make和make install的一部分运行吗?
将数据导入Perl 6 Native指针并不是什么大不了的事:
sub memcpy( Pointer[void] $source, Pointer[void] $destination, int32 $size ) is native { * };
my Blob $blob = Blob.new(0x22, 0x33);
my Pointer[void] $src-memcpy = nativecast(Pointer[void], $blob);
my Pointer[void] $dest-memcpy = malloc( 32 );
memcpy($src-memcpy,$dest-memcpy,2);
my Pointer[int] $inter = nativecast(Pointer[int], $dest-memcpy);
say $inter; # prints NativeCall::Types::Pointer[int]<0x4499560>
Run Code Online (Sandbox Code Playgroud)
但是,我认为没有办法让它们脱离Pointer[int]另一个而不是创建一个函数来完成它,因为它nativecast显然是在相反的方向上工作,或者至少不是在向非本地类型转换的方向(这应该是显而易见的名称).你会怎么做?
更新:例如,使用数组会使其更加可行.然而
my $inter = nativecast(CArray[int16], $dest);
.say for $inter.list;
Run Code Online (Sandbox Code Playgroud)
这有效,但会产生错误: Don't know how many elements a C array returned from a library
更新2:继克里斯托夫的回答(谢谢!)之后,我们可以对此进行更多细化,然后我们将这些值重新纳入 …
我希望能够在REPR CStruct/CPointer的类中使用双指针:
typedef struct CipherContext {
void *cipher;
const uint8_t *key;
size_t key_len;
const uint8_t *path;
size_t path_len;
size_t block_size;
void *handle;
int (*cipher_init)(void **, const uint8_t *, size_t);
int (*cipher_encode)(void *, const uint8_t *, uint8_t *, size_t);
int (*cipher_decode)(void *, const uint8_t *, uint8_t *, size_t);
void (*cipher_free)(void *);
const uint8_t *(*cipher_strerror)(int);
} CipherContext;
int cipher_context_init(CipherContext **, const uint8_t *, size_t, const uint8_t *, size_t, size_t);
int cipher_context_encode(CipherContext *, const uint8_t *, uint8_t *, size_t);
int cipher_context_decode(CipherContext *, const …Run Code Online (Sandbox Code Playgroud) 软呢帽 33 乐
我正在尝试使用 Raku 的 NativeCall 与 libX11.so 对话以打印出我的屏幕和显示:
use NativeCall;
class Display is repr('CStruct') { has Pointer $.DisplayPtr };
# libX11.so --> X11
sub XOpenDisplay(Str $name = ':0') returns Display is native('X11') { * }
sub XDefaultScreen(Display $) returns int32 is native('X11') { * }
my Display $display = XOpenDisplay()
or die "Can not open display";
my int $screen = XDefaultScreen($display);
print "display = <" ~ $display ~ ">\n";
print "screen = <" ~ $screen ~ ">\n";
$ …Run Code Online (Sandbox Code Playgroud) 这是一个NativeCall问题。
我有 8 个字节(小端)表示CArray内存地址。我如何创建一个Pointer出来呢?
(CArray和Pointer是 NativeCall 的两种 C 兼容类型。 s 长 8 个字节。事情应该排成一行,但是如何以 NativeCall 可接受的方式Pointer将 a 中的指针地址放入 aCArray中?)Pointer
好吧,所以我是Perl和Perl 6的新手.我以为我会看到我是否可以分叉和管道工作,但到目前为止一直无法做到.这是我的Perl 6代码:
use NativeCall;
# http://www.perlmonks.org/?node_id=989766
our sub c_close(int32) returns int32 is native is symbol('close') { * }
sub pipe(CArray[int32]) returns int32 is native { ... }
our sub c_read(int32, Str is encoded('utf8'), size_t) returns ssize_t is native is symbol('read') { *}
our sub c_write(int32, Str is encoded('utf8'), size_t) returns ssize_t is native is symbol('write') { *}
our sub c_wait(int32 is rw) is native is symbol('wait') { * }
sub c_puts(Str) is native is symbol("puts") { * }
sub …Run Code Online (Sandbox Code Playgroud) 我试图在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中做到这一点.