我正在使用NativeCall接口;有一个接受回调的C函数,定义如下:
typedef void (* ExifContentForeachEntryFunc) (ExifEntry *,void *user_data); void exif_content_foreach_entry (ExifContent *content,ExifContentForeachEntryFunc func,void *user_data);
我的第一次采取是:
sub exif_content_foreach_entry(ExifContent $exifcontent,&func (ExifEntry $entry,Buf $data),Buf $user_data) is native(LIB) is export { * }
Internal error: unhandled dyncall callback argument type in method CALL-ME at /opt/rakudo-pkg/share/perl6/sources/24DD121B5B4774C04A7084827BFAD92199756E03 (NativeCall) line 588
如果我忽略user_data参数,一切正常,所以声明的其余部分是正常的:我只是不能将任何额外的数据传递给回调函数.
在其他情况下,我使用Buf将一块(可能的)二进制数据传递给C函数并且它工作;这里的区别是回调函数.
知道怎么解决这个问题吗?
(使用perl6 2018.03)
解决方法
我不确定如何将Buf作为用户数据传递,因为Buf不是本机类型.但您可以使用例如CStruct代替:
class UserData is repr('CStruct') { has int32 $.dummy; }
然后宣言将是:
sub exif_content_foreach_entry( ExifContent $exifcontent,UserData $data),UserData $user_data) is native(LIB) is export { * }
并且可以声明和定义回调,例如:
sub my-callback (ExifEntry $entry,UserData $data) { say "In callback"; say "Value of data: ",$data.dummy; }
编辑:
下面是一个解决方法,使用闭包将类似Buf的Perl 6类型(即非本机类型)传递给回调.例如:
my $buf = Buf.new( 1,2,3); my $callback = my sub (ExifEntry $entry,UserData $data) { my-callback( $entry,$buf); }
然后像这样声明真正的回调my-callback:
sub my-callback (ExifEntry $entry,Buf $data) { say "In callback"; say "Value of data: ",$data; }
exif_content_foreach_entry( $content,&$callback,$data );