返回

Dart ffi NativeCallback 必须是子类型的解决方案:类型不匹配错误详解

Linux

Dart ffi NativeCallback 必须是子类型的解决方案

在使用 Dart ffi 时,尝试使用 NativeCallable<EventHandlerFunction>.isolateLocal 函数注册回调时,你可能会遇到一个错误,提示 "The type 'UnsignedInt Function(UnsignedInt, UnsignedInt, UnsignedInt, Pointer)' must be a subtype of 'UnsignedInt Function(UnsignedInt, UnsignedInt, UnsignedInt, Pointer)' for 'NativeCallable'。"。

错误原因

这个错误的根源在于回调函数的类型与预期类型不匹配。让我们仔细看看你的代码:

typedef EventHandlerFunction = UnsignedInt Function(UnsignedInt inEvent, UnsignedInt inPropertyID, UnsignedInt inParam, ffi.Pointer<Void> inContext);

UnsignedInt handleStateEvent(UnsignedInt inEvent, UnsignedInt inPropertyID, UnsignedInt inParam, ffi.Pointer<Void> inContext) {
  // ...
}

final callback = NativeCallable<EventHandlerFunction>.isolateLocal(handleStateEvent, exceptionalReturn: 0);

你的 EventHandlerFunction 类型声明似乎是正确的,因为它与 NativeCallable 预期的类型相匹配。然而,在 handleStateEvent 函数中,返回值类型 UnsignedIntEventHandlerFunction 类型声明中的预期类型 void 不一致。

解决方案

为了解决这个错误,你需要确保 handleStateEvent 函数的返回值类型与 EventHandlerFunction 类型声明中的类型相匹配。在你的情况下,EventHandlerFunction 类型声明期望返回 void,因此你需要修改 handleStateEvent 函数的返回值类型。

以下是修改后的代码:

typedef EventHandlerFunction = void Function(UnsignedInt inEvent, UnsignedInt inPropertyID, UnsignedInt inParam, ffi.Pointer<Void> inContext);

void handleStateEvent(UnsignedInt inEvent, UnsignedInt inPropertyID, UnsignedInt inParam, ffi.Pointer<Void> inContext) {
  // ...
}

final callback = NativeCallable<EventHandlerFunction>.isolateLocal(handleStateEvent, exceptionalReturn: 0);

结论

通过进行这个修改,你的代码现在应该可以正常工作,并且你应该能够在 Dart ffi 中注册回调函数。

常见问题解答

  1. 为什么会出现这个错误?

    • 这个错误是因为回调函数的类型与预期类型不匹配。
  2. 如何解决这个错误?

    • 确保回调函数的返回值类型与类型声明中的类型相匹配。
  3. 为什么我的 handleStateEvent 函数需要返回 void

    • 因为 EventHandlerFunction 类型声明期望回调函数返回 void
  4. 除了类型不匹配之外,还有什么可能导致这个错误?

    • 检查 EventHandlerFunction 类型声明和 handleStateEvent 函数的名称和参数是否正确。
  5. 除了 ffi,还有什么其他方法可以在 Dart 中注册回调函数?

    • 你可以使用 dart:js 包来与 JavaScript 回调进行交互。