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>
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;
This works, but yields the error: Don't know how many elements a C array returned from a library
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;
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?
Complete example:
use NativeCall;
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(nativesizeof(int16));
memcpy($dest, $src, nativesizeof(int16));
my $inter = nativecast(Pointer[int16], $dest);
say $inter.deref.fmt('%x');
I assume you were looking for the deref
method, but there were a few other issues with your code:
int32
instead of size_t
in the declaration of memcpy
memcpy
, which means you were copying two bytes read from uninitialized memory into your supposedly immutable Blobint
where you probably should have used a sized integer type such as int16
Also note the use of plain Pointer
in the declaration of memcpy
, which will allow you to pass in any pointer type without having to cast constantly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With