dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.2k stars 1.57k forks source link

[vm/ffi] Introduce a `Pointer<T extends Struct>.refWithFinalizer(finalizer, token)` #56796

Open dcharkes opened 3 weeks ago

dcharkes commented 3 weeks ago

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:

  1. calloc a Pointer<MyStruct>
  2. cast the struct to <Uint8>
  3. call asTypedList with calloc.nativeFree as finalizer
  4. 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);
codesculpture commented 3 weeks ago

Hey @dcharkes , what's Pointer<Void> token for ?

dcharkes commented 2 weeks ago

See https://api.flutter.dev/flutter/dart-ffi/NativeFinalizer/attach.html documentation.