sdk
sdk copied to clipboard
Implement support for creating isolate independent native functions code in dart:ffi
The idea of isolate independent native code is described in finalization proposal
Assigning to myself for the initial design.
Another use case for this is async callbacks: we could potentially compile a function using the Dart API turning a callback into Dart_PostCObject
. (Instead of implementing that in the VM or as a way of implementing that in the VM.)
- https://github.com/dart-lang/sdk/issues/37022
@mraleph is this work complete sufficiently to close out the issue?
This is in early design stages.
half year passed and only 2 month left to Dart 2.18 release, any update on this?
@dcharkes has done some initial prototyping and we have been discussing different approaches.
It currently looks possible that we decide against implementing isolate independent code as a embedded DSL and choose to follow cgo route instead - simplify bundling C/C++ code with the Dart packages as this would address the same problem in a more robust way. But the final decision is not yet made.
@calvin2021y We have a prototype on https://dart-review.googlesource.com/c/sdk/+/246241/ if you know how to build the Dart SDK and want to try it out.
@dcharkes has done some initial prototyping and we have been discussing different approaches.
It currently looks possible that we decide against implementing isolate independent code as a embedded DSL and choose to follow cgo route instead - simplify bundling C/C++ code with the Dart packages as this would address the same problem in a more robust way. But the final decision is not yet made.
I like this much better, will try the Dart SDK branch.
Any update about this @calvin2021y ?
@dcharkes @mraleph will this be going into 2.19? Asking for documentation update purposes
@dcharkes @mraleph will this be going into 2.19? Asking for documentation update purposes
No. We're exploring bundling C/C++ code with Dart packages instead.
Cleared the milestone to reflect the change in our plans.
Side note, if you just need a finalizer to reliably free a pointer, this works without any extra C code for a guaranteed freeing of your native resources:
// filename: lib/src/utils/memory.dart
/// A generic [NativeFinalizer] to free any pointer by calling the C function
/// `free`. It's kind of like a workaround to combat the restriction of
/// [NativeFinalizer] (which only accepts a C function, not a Dart
/// function).
final freenalizer = NativeFinalizer(DynamicLibrary.executable().lookup('free'));
Then,
import 'dart:ffi';
import 'package:mypackage/src/utils/memory.dart';
class Foo extends Finalizable {
Pointer<X> _ptr = calloc();
Foo() {
freenalizer.attach(this, _ptr.cast());
}
}
Side note, if you just need a finalizer to reliably free a pointer, this works without any extra C code for a guaranteed freeing of your native resources:
// filename: lib/src/utils/memory.dart /// A generic [NativeFinalizer] to free any pointer by calling the C function /// `free`. It's kind of like a workaround to combat the restriction of /// [NativeFinalizer] (which only accepts a C function, not a Dart /// function). final freenalizer = NativeFinalizer(DynamicLibrary.executable().lookup('free'));
Then,
import 'dart:ffi'; import 'package:mypackage/src/utils/memory.dart'; class Foo extends Finalizable { Pointer<X> _ptr = calloc(); Foo() { freenalizer.attach(this, _ptr.cast()); } }
That is not entirely true. On Windows WinCoTaskMemFree
needs to be used when using calloc
from package:ffi
. See https://github.com/dart-lang/native/issues/910 for making an abstraction for this.
How would you embed C++ code when compiling Dart as an AOT executable and when running in JIT mode?
How would you embed C++ code when compiling Dart as an AOT executable and when running in JIT mode?
Currently, you bundle dynamic libraries.
- In Flutter use the FFI plugin template.
- In Dart standalone, use a
bin/setup.dart
script that downloads or builds your dynamic libraries. (Note your downstream users need to all rundart run yourpackage:setup
before stuff works.
This is not ideal.
Future:
- You add your C++ code to the pub package and create a
bin/native.dart
CLI that can be invoked by thedart run
anddart compile
commands to build the native assets (static or dynamic library). Then useFfiNative
for a more declarative binding. This is WIP. Some related issues:- https://github.com/dart-lang/sdk/issues/49803 (design is out of date)
- https://github.com/dart-lang/sdk/issues/50097
- JIT will only support dynamic libraries. But in AOT we should be able to link in static libraries and let the native linker get rid of code that is not referenced (https://github.com/dart-lang/sdk/issues/49418). I built a prototype of this in https://dart-review.googlesource.com/c/sdk/+/251263. This is also very much WIP.