我正在使用NativeCall接口.
该库将多次调用我的回调函数.
这很好.我可以使用正确的签名声明我的回调,将其作为&callback传入,并且库调用sub就好了.
它还能够将有效负载void*指针设置为我想要的任何东西,并且它将包含在我的回调函数调用中.
我可以隐藏一个Perl Str,例如,在有效载荷中成功往返吗?
sub set_userdata(Pointer) returns int32 is native { ... }
sub set_callback(&callback(Pointer $userdata --> int32)) returns int32 is native { ... }
sub callback(Pointer $userdata) returns int32 {
my Str $mystring = ???
...
}
my Str $my-userdata-string;
set_userdata(???);
set_callback(&callback);
Run Code Online (Sandbox Code Playgroud)
看起来它可能适用于一些绑定,"是rw",nativecast()和/或.deref.
可以只使用一个本地表示在这样的情况下(如CStruct,CArray,和CPointer),或者一个Blob.您还有责任确保userdata从Perl 6的角度保持对您传递的内容的引用,因此GC不会回收传递给C函数的内存.
内存管理是你不能将任何旧的Perl 6对象传递给C函数的原因:GC无法知道对象是否仍然可以通过它无法反省的某些C数据结构到达.在像MoarVM这样的VM中,对象随着时间的推移在内存中移动,这也是垃圾收集过程的一部分,这意味着C代码可能最终会出现过时的指针.
另一种策略不是根本不传递指针,而是传递一个整数并使用它来索引到一个对象数组.(这就是MoarVM内部的libuv绑定如何跟踪VM级别的回调,fwiw.)