NativeCallable<T extends Function>.listener 构造函数
- @DartRepresentationOf("T") Function callback
构建一个可以从任何线程调用的原生可调用(NativeCallable)。
当原生代码调用函数 nativeFunction 时,参数将通过 SendPort 发送到创建了原生可调用的 Isolate,然后回调将被触发。
原生代码不会等待回调的响应,因此只支持返回 void 的函数。
回调将在未来的某个时刻被调用。原生调用者不能假定回调会立即运行。传递给回调的资源(如 malloc'd 内存指针、输出参数)必须在调用完成前保持有效。
当不再需要时,必须关闭此回调。创建了回调的 Isolate 将保持活动状态直到调用 close。调用 NativeCallable.close 后,从原生代码调用 nativeFunction 将导致未定义的行为。
例如
import 'dart:async';
import 'dart:ffi';
import 'package:ffi/ffi.dart';
// Processes a simple HTTP GET request using a native HTTP library that
// processes the request on a background thread.
Future<String> httpGet(String uri) async {
final uriPointer = uri.toNativeUtf8();
// Create the NativeCallable.listener.
final completer = Completer<String>();
late final NativeCallable<NativeHttpCallback> callback;
void onResponse(Pointer<Utf8> responsePointer) {
completer.complete(responsePointer.toDartString());
calloc.free(responsePointer);
calloc.free(uriPointer);
// Remember to close the NativeCallable once the native API is
// finished with it, otherwise this isolate will stay alive
// indefinitely.
callback.close();
}
callback = NativeCallable<NativeHttpCallback>.listener(onResponse);
// Invoke the native HTTP API. Our example HTTP library processes our
// request on a background thread, and calls the callback on that same
// thread when it receives the response.
nativeHttpGet(uriPointer, callback.nativeFunction);
return completer.future;
}
// Load the native functions from a DynamicLibrary.
final DynamicLibrary dylib = DynamicLibrary.process();
typedef NativeHttpCallback = Void Function(Pointer<Utf8>);
typedef HttpGetFunction = void Function(
Pointer<Utf8>, Pointer<NativeFunction<NativeHttpCallback>>);
typedef HttpGetNativeFunction = Void Function(
Pointer<Utf8>, Pointer<NativeFunction<NativeHttpCallback>>);
final nativeHttpGet =
dylib.lookupFunction<HttpGetNativeFunction, HttpGetFunction>(
'http_get');
实现
factory NativeCallable.listener(
@DartRepresentationOf("T") Function callback) {
throw UnsupportedError("NativeCallable cannot be constructed dynamically.");
}