c - 如何将用户数据传递给回调函数

标签 c callback raku nativecall

我正在处理 NativeCall 接口(interface);有一个接受回调的 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 将一 block (可能)二进制数据传递给 C 函数并且它起作用了;这里的区别是回调函数。 知道如何解决这个问题吗?

(使用 perl6 2018.03)

最佳答案

我不确定如何将 Buf 作为用户数据传递,因为 Buf 不是 native 类型。但是您可以使用例如 CStruct 代替:

class UserData is repr('CStruct') {
    has int32 $.dummy;
}

那么声明将是:

sub exif_content_foreach_entry(
    ExifContent $exifcontent, 
    &func (ExifEntry $entry, 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;
}

编辑:

这里有一个解决方法,可以使用闭包将 Perl 6 类型(如 Buf)(即不是 native 类型)传递给回调。例如:

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 );

关于c - 如何将用户数据传递给回调函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50129510/

相关文章:

javascript - Mongoose find() 回调问题

raku - 在 Ubuntu 15.10 上安装 Perl6 和 Panda。 bootstrap.pl 的问题

c - 奇怪的 sqlite 数据库字符串文件路径错误

ios - 如何在 Swift 中将异步 Parse Login 实现为 CallBack 函数

c - 在c中获取否定地址

javascript - 如何从 javascript 回调返回字符串

regex - 为什么我使用这些 Raku 正则表达式得到不同的回溯?

date - 为什么 `later` 方法会导致 `Date` 范围内的无限范围?

c - SimGrid 中的并行任务

c - C 中的结构体初始化