@H_502_1@
将数据导入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>
但是,除了创建一个函数之外,我认为没有办法让它们脱离Pointer [int],因为nativecast
显然在相反的方向上工作,或者至少不是在向非本地类型的方向投射(它的名字应该很明显).你会怎么做?
更新:例如,使用数组会使其更加可行.然而
my $inter = nativecast(CArray[int16],$dest); .say for $inter.list;
这有效,但产生错误:不知道C数组从库返回了多少元素
更新2:继Christoph’s answer之后(谢谢!),我们可以对此进行更多细化,然后我们将这些值重新纳入Buf
sub malloc(size_t $size --> Pointer) is native {*} sub memcpy(Pointer $dest,Pointer $src,size_t $size --> Pointer) is native {*} my $blob = Blob.new(0x22,0x33); my $src = nativecast(Pointer,$blob); my $dest = malloc( $blob.bytes ); memcpy($dest,$src,$blob.bytes); my $inter = nativecast(Pointer[int8],$dest); my $cursor = $inter; my Buf $new-blob .= new() ; for 1..$blob.bytes { $new-blob.append: $cursor.deref; $cursor++; } say $new-blob;
我们需要将指针强制转换为缓冲区使用的完全相同的类型,然后we use pointer arithmetic将其运行.但是,我们使用$blob.bytes来知道何时结束循环,而且它仍然是一种hacky.会有更直接的方式吗?或者只是一种使用Bufs / Blob的方式,以便它们可以轻松地复制到Native领域并返回?
解决方法
完整的例子:
use NativeCall; sub malloc(size_t $size --> Pointer) is native {*} sub memcpy(Pointer $dest,$blob); my $dest = malloc(nativesizeof(int16)); memcpy($dest,nativesizeof(int16)); my $inter = nativecast(Pointer[int16],$dest); say $inter.deref.fmt('%x');
我假设您正在寻找deref方法,但您的代码还存在一些其他问题:
>在memcpy的声明中使用int32而不是size_t
> memcpy参数的错误顺序,这意味着你将从未初始化的内存中读取的两个字节复制到你认为不可变的Blob中
>使用plain int,你可能应该使用一个大小的整数类型,如int16
还要注意在memcpy的声明中使用普通指针,它允许你传入任何指针类型而不必不断地进行转换.