You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart ffi传入回调报错:dart:ffi仅支持从原生代码调用静态Dart函数

错误原因

Pointer.fromFunction() 只支持传入顶层函数、类静态函数,不支持闭包、实例方法、局部函数这类可能携带上下文的动态函数,你当前代码直接将用户传入的动态callback参数传给fromFunction,就会触发这个编译错误。

解决方法

你可以通过静态存储中转用户自定义回调的方式实现需求,具体修改如下:

  1. 先定义全局变量存储用户传入的回调,再单独写一个符合要求的顶层静态回调函数,专门用于传给FFI:
// 存储用户自定义的回调
CallbackFuncDart? _userCallback;

// 顶层静态回调函数,无上下文,符合fromFunction的入参要求
void _staticCallback(int eventId) {
  _userCallback?.call(eventId);
}

typedef CallbackFunc = Void Function(Uint32);
typedef CallbackFuncDart = void Function(int);
  1. 修改你的封装方法,先把用户传入的回调存入全局变量,再将静态函数转为指针传给底层:
static int SetCallback({required CallbackFuncDart callback}) {
  // 存储用户自定义回调
  _userCallback = callback;
  // 传入静态函数生成指针
  Pointer<NativeFunction<CallbackFunc>> pointer = Pointer.fromFunction(_staticCallback);

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

注意事项

  • 你当前使用的Dart 2.15开发版已经支持C回调Dart能力,该特性从Dart 2.17版本开始正式稳定,建议升级到更高稳定版本避免已知兼容问题
  • 上述方案默认是单回调场景,如果需要同时支持多个不同回调,可以用Map存储不同标识对应的用户回调,C侧触发回调时携带标识,Dart静态函数根据标识取出对应回调执行即可
  • 生成的函数指针需要在C侧可能调用回调的全生命周期内被Dart侧持有,避免被GC回收导致野指针崩溃,建议将指针存为类静态属性或者全局变量,不要定义为方法内的局部变量
  • 如果你的回调有返回值,需要给fromFunction传入第二个参数作为异常触发时的默认返回值,避免FFI调用直接崩溃,例如返回值为int的写法为Pointer.fromFunction(func, 0)

内容的提问来源于stack exchange,提问作者azan-n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 23:36:00