I'm trying to use NativeCall to interact with some C functions.
For one case, I need to pass in pointers that get updated by the function, so it wants a pointer to a pointer, 'void **'.
I tried it like this:
class Foo
{
has Pointer $.first;
has Pointer $.last;
sub somefunc(Pointer is rw, Pointer is rw, Str) is native { * }
method myfunc(Str $arg) {
somefunc($!first, $!last, $arg);
}
}
It doesn't work. The pointers don't get updated by the function.
Since a C array is basically a pointer to a pointer, I can fake it like this:
class Foo
{
has Pointer $.first;
has Pointer $.last;
sub somefunc(CArray[Pointer], CArray[Pointer], Str) is native { * }
method myfunc(Str $arg) {
my $first = CArray[Pointer].new($!first);
my $last = CArray[Pointer].new($!last);
somefunc($first, $last, $arg);
$!first = $first[0];
$!last = $last[0];
}
}
It works fine like this. It just seems like the "is rw" should force the pointer to pointer and it should work the first way.
What am I doing wrong?
Last I checked, NativeCall
still had some rough edges that at times necessitate a bit of creativity; this might be one of those cases.
One workaround I know of is to just use pointer-sized integers (specifically, size_t
or ssize_t
) as parameter and attribute types on the Perl6 side1, which should work as expected with is rw
.
It's easy to convert between integers and pointers: use prefix +
, .Int
or even just assignment to an integer-typed variable to convert to integer, and Pointer.new(…)
or nqp::box_i(…, Pointer)
for the other direction.
If so desired, accessor methods can be used to automate this conversion.
1 if you do go this way, a definition such as constant intptr = ssize_t
will help readability
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