// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. // SharedObjects=ffi_test_functions import 'dart:ffi'; import 'dart:isolate'; import 'package:ffi/ffi.dart'; import 'dylib_utils.dart'; void main() async { final myFinalizable2 = await Isolate.run(() => MyFinalizable()); print(myFinalizable2); print(myFinalizable2.pointer); // This would crash if a NativeFinalizer would have been attached and run // eagerly on `Isolate.exit`. print(myFinalizable2.pointer.value); } @pragma('vm:deeply-immutable') final class MyFinalizable implements Finalizable { final Pointer pointer; MyFinalizable._(this.pointer); factory MyFinalizable() { final pointer = calloc(sizeOf(), 10).cast(); pointer.value = 123; final result = MyFinalizable._(pointer); newFinalizableHandle( result, pointer.cast(), 0, freeFinalizer, // Not the signature of `free`! ); return result; } } final calloc = dlopenPlatformSpecific("ffi_test_functions") .lookup Function(Size, Size)>>('Calloc') .asFunction Function(int, int)>(); final freeFinalizer = dlopenPlatformSpecific( "ffi_test_functions", ).lookup>('FreeFinalizer'); final Dart_FinalizableHandle Function( Object, Pointer, int, Dart_HandleFinalizer, ) newFinalizableHandle = _findDartApiFunction('Dart_NewFinalizableHandle') .cast< NativeFunction< Dart_FinalizableHandle Function( Handle, Pointer, IntPtr, Dart_HandleFinalizer, ) > >() .asFunction(); final void Function(Dart_FinalizableHandle, Object) deleteFinalizableHandle = _findDartApiFunction('Dart_DeleteFinalizableHandle') .cast>() .asFunction(); Pointer _findDartApiFunction(String name) { final dartApi = NativeApi.initializeApiDLData.cast(); var entry = dartApi.ref.functions; while (true) { final entryName = entry.ref.name.cast().toDartString(); if (entryName == name) { return entry.ref.function; } if (name == 'Dart_Null') { throw StateError('Dart API function with $name not found.'); } entry++; } } final class DartApi extends Struct { @Int() external int major; @Int() external int minor; external Pointer functions; } final class DartApiEntry extends Struct { external Pointer name; external Pointer function; } final class _Dart_FinalizableHandle extends Opaque {} typedef Dart_HandleFinalizer = Pointer>; typedef Dart_HandleFinalizerFunction = Void Function(Pointer isolate_callback_data, Pointer peer); typedef DartDart_HandleFinalizerFunction = void Function(Pointer isolate_callback_data, Pointer peer); typedef Dart_FinalizableHandle = Pointer<_Dart_FinalizableHandle>;