Service constructor
Service(
- String libname
Creates a Service by opening the shared library at libname, binding
the five mandatory C functions, and registering the notification callback.
libname is the path passed to DynamicLibrary.open — typically just
the file name (e.g. "libaudio.so") when the library is bundled next to
the executable.
Implementation
Service(this.libname) {
try {
lib = DynamicLibrary.open(libname);
startService = lib
.lookup<NativeFunction<Void Function()>>('start_service')
.asFunction<void Function()>();
stopService = lib
.lookup<NativeFunction<Void Function()>>('stop_service')
.asFunction<void Function()>();
getNextMessage = lib
.lookup<NativeFunction<Pointer<BackendMsg> Function()>>(
'get_next_message',
)
.asFunction<Pointer<BackendMsg> Function()>();
freeMessage = lib
.lookup<NativeFunction<Void Function(Pointer<BackendMsg>)>>(
'free_message',
)
.asFunction<void Function(Pointer<BackendMsg>)>();
_setMessageCallback = lib
.lookup<
NativeFunction<
Void Function(Pointer<NativeFunction<_NotifyNative>>)>>(
'set_message_callback')
.asFunction<void Function(Pointer<NativeFunction<_NotifyNative>>)>();
// NativeCallable.listener is safe to call from any thread: the C++ worker
// posts the notification and Dart schedules _onNotify on the event loop.
_callable = NativeCallable<_NotifyNative>.listener(_onNotify);
// Register a GC finalizer so that _callable is closed even if a subclass
// constructor throws after super() — in that case dispose() is never
// called and the NativeCallable would otherwise keep the isolate alive
// forever. dispose() calls _finalizer.detach(this) to prevent the
// finalizer from firing again after an explicit close.
_finalizer.attach(this, _callable!, detach: this);
_setMessageCallback(_callable!.nativeFunction);
} catch (_) {
// Construction failed (missing symbol, library not found, …).
// Mark as disposed so that dispose() becomes a no-op if called via
// try/finally. Detach the finalizer (no-op if never attached) and close
// _callable if it was created before the exception.
_disposed = true;
_messageController.close();
_finalizer.detach(this);
_callable?.close();
rethrow;
}
}