【问题标题】:Callbacks in Dart: dart:ffi only supports calling static Dart functions from native codeDart 中的回调:dart:ffi 仅支持从原生代码调用静态 Dart 函数
【发布时间】:2021-10-12 08:39:02
【问题描述】:

这篇文章是 Github 问题 here 的副本。

dart --version Dart SDK 版本:2.15.0-116.0.dev (dev) (Thu Sep 16 09:47:01 2021 -0700) on "linux_x64"

我一直在查找 examples 的回调,并且我试图让回调在 FFI 中为我工作。

我现在的情况

我的库中有一个函数,它需要一个指向函数的指针。 ffigen 生成的相同绑定对我来说似乎是正确的。

int SetCallback(
    CallbackType callback,
  ) {
    return _SetCallback(
      callback,
    );
  }

  late final _SetCallbackPtr =
      _lookup<NativeFunction<Int32 Function(CallbackType)>>(
          'SetCallback');
  late final _SetCallback =
      _SetCallbackPtr.asFunction<int Function(CallbackType)>();

在哪里,typedef CallbackType = Pointer&lt;NativeFunction&lt;Void Function(Uint32)&gt;&gt;;

我在这里要做的是在 Dart 中设置此回调,将其传递给 FFI,本质上将它用作我在 C 中的回调。在我的 API 中,它从 FFI 代码中抽象出来(这意味着我有一个 MyLibrary 类,其中包含用户将直接调用的静态函数,而后者又从我创建的 MyNativeLibrary 类的对象 _nativeLibrary 中调用函数),我有:

  static int SetCallback({required CallbackFuncDart callback}) {
    Pointer<NativeFunction<CallbackFunc>> pointer = Pointer.fromFunction(callback);

    int status = _nativeLibrary.SetCallback(
      pointer,
    );
    if (STATUS_OK != status) {
      throw LibLexemeException(status);
    }
    return status;
  }

typedef CallbackFunc = Void Function(Uint32);
typedef CallbackFuncDart = void Function(int);

虽然the sqlite ffi example 在这里声明

dart:ffi 尚不支持的功能:

Callbacks from C back into Dart.

我相信文档尚未更新以反映 the samples here. 的更改。由于样本没有任何 C/C++ 文件,或者不了解 C 函数的工作原理,因此这些样本还不是很清楚。即便如此,我认为this example 包含一个段(最后一个代码块),其中一个 Dart 函数作为回调传递,我已经在我的程序中复制了该回调。我不清楚这将如何工作,但在尝试编译我的程序时,我得到:

ERROR: ../lib/library_lexeme.dart:180:74: Error: fromFunction expects a static function as parameter. dart:ffi only supports calling static Dart functions from native code. Closures and tear-offs are not supported because they can capture context.
ERROR:     Pointer<NativeFunction<CallbackFunc>> pointer = Pointer.fromFunction(callback);

【问题讨论】:

    标签: flutter dart ffi


    【解决方案1】:

    简短的版本是您不能将回调作为参数传递:

    static int SetCallback({required CallbackFuncDart callback}) {
        Pointer<NativeFunction<CallbackFunc>> pointer = Pointer.fromFunction(callback); // <-- this isn't considered a static function
    

    这很烦人,但您必须使用提前定义的静态函数才能从 C 调用您的 dart 回调。

    【讨论】:

      猜你喜欢
      • 2020-03-03
      • 1970-01-01
      • 1970-01-01
      • 2020-10-02
      • 2021-02-24
      • 2019-05-25
      • 2023-01-16
      • 2019-09-20
      • 1970-01-01
      相关资源
      最近更新 更多