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