call asTypedList with calloc.nativeFree as finalizer
call Struct.create<MyStruct> with the typed data
Maybe we could simplify step 2 to 4 by introducing:
/// Extension on [Pointer] specialized for the type argument [Struct].
@Since('2.12')
extension StructPointer<T extends Struct> on Pointer<T> {
/// A Dart view of the struct referenced by this pointer.
///
/// Attaches [finalizer] to the backing store of the struct.
/// The pointer (`this`) must _not_ be used anymore if the struct is _not_ guaranteed to be kept alive.
/// Prefer doing any native calls with the pointer _before_ calling `refWithFinalizer`.
///
/// Reading [ref] creates a reference accessing the fields of this struct
/// backed by native memory at [address].
/// The [address] must be aligned according to the struct alignment rules of
/// the platform.
///
/// Assigning to [ref] copies contents of the struct into the native memory
/// starting at [address].
///
/// This extension method must be invoked on a receiver of type `Pointer<T>`
/// where `T` is a compile-time constant type.
external T refWithFinalizer(Pointer<NativeFinalizerFunction>? finalizer, @Since('3.1') Pointer<Void>? token);
It's quite common to want to return a struct from Dart code using
dart:ffi
and having a call with the pointer inside that code (https://github.com/dart-lang/native/issues/1601, https://github.com/dart-lang/native/issues/1480#issuecomment-2348112178).That currently requires the following dance:
calloc
aPointer<MyStruct>
cast
the struct to<Uint8>
asTypedList
withcalloc.nativeFree
as finalizerStruct.create<MyStruct>
with the typed dataMaybe we could simplify step 2 to 4 by introducing: