Implement support for creating isolate independent native functions code in dart:ffi
mraleph opened this issue ยท 16 comments
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.)
@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 ?
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 dart-lang/native#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.dartscript that downloads or builds your dynamic libraries. (Note your downstream users need to all rundart run yourpackage:setupbefore stuff works.
This is not ideal.
Future:
- You add your C++ code to the pub package and create a
bin/native.dartCLI that can be invoked by thedart runanddart compilecommands to build the native assets (static or dynamic library). Then useFfiNativefor a more declarative binding. This is WIP. Some related issues: - 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 (#49418). I built a prototype of this in https://dart-review.googlesource.com/c/sdk/+/251263. This is also very much WIP.