从本机指针中获取数据 [英] Getting data out of Native pointers

查看:52
本文介绍了从本机指针中获取数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将数据放入 Perl 6 Native 指针没什么大不了的:

It's no big deal to get data into Perl 6 Native pointers:

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 显然在相反的方向工作,或者至少不是在转换为非本地类型的方向(这应该是显而易见的)按它的名字).你会怎么做?

However, I see no way of getting them out of the Pointer[int] other than creating a function to do it, since nativecast apparently works in the opposite direction, or at least not in the direction of casting to non-native types (which should be obvious by its name). How would you do that?

更新:例如,使用数组会使其更可行.不过

Update: For instance, using an Array would make it more workable. However

my $inter = nativecast(CArray[int16], $dest);
.say for $inter.list;

这可行,但会产生错误:不知道从库返回的 C 数组有多少个元素

This works, but yields the error: Don't know how many elements a C array returned from a library

更新 2:按照 Christoph 的回答(谢谢!),我们可以详细说明一下更深入地了解这一点,我们将这些值放回 Buf

Update 2: Following Christoph's answer (thanks!), we can ellaborate it a little bit more into this, and we get to put the values back into a 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;

我们需要将指针强制转换为缓冲区使用的完全相同的类型,然后我们使用指针算法来运行它.然而,我们使用 $blob.bytes 来知道什么时候结束循环,它仍然有点hacky.有没有更直接的方法?或者只是一种使用 Bufs/Blob 的方式,以便它们可以轻松复制到 Native 领域并返回?

We need to cast the pointer to exactly the same type used by the buffer, and then we use pointer arithmetic to run over it. However, we use $blob.bytes to know when to end the loop, and it's still kind of hacky. Would there be a more direct way? Or just a way of working with Bufs/Blobs so that they can be copied easily to the Native realm and back?

推荐答案

使用 NativeHelpers::Blob:

use NativeCall;
use NativeHelpers::Blob;

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 Blob $esponja = blob-from-pointer( $inter, :2elems, :type(Blob[int8]));
say $esponja;

这个程序扩展了克里斯托夫的答案 添加 blob-from-pointer 函数,该函数将返回原始 blob:Blob[int8]:0x<22 33>.这个答案现在也在在文档中

This program extends Christoph's answer adding the blob-from-pointer function, which will return the original blob: Blob[int8]:0x<22 33>. This answer is also now in the documentation

这篇关于从本机指针中获取数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆