-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remaining tasks for dart:ffi for Dart 2.6 #38358
Comments
@mit-mit Would it make sense to have a centralized place under https://dart.dev/guides for introduction to |
I updated the list to include extension methods. |
I've been experimenting with extension methods and providing feedback. Note that we cannot land extension methods until the extension methods flag is on by default. Though that should happen before 2.6. |
Currently the docs are here: https://dart.dev/guides/libraries/c-interop. But we clearly need to expand them for 2.6. |
Hi @mit-mit, In dart 2.5 announcement, you mentioned about code generation based on C header files. I didn't find a place to discuss that topic, so posting here. FFI is foreign to me as it is, But generators and parsers are not. I'd love to give this a try, would you mind guiding me?. Looking at the examples at https://github.com/dart-lang/samples/tree/master/ffi. The difficult part is the intermediate representation of header files which the generator would understand and generate code for accordingly. This would probably require a parser for c headers 😅. A dart-only approach in which the bindings are hand-written, to me looks like: // interop.dart
@C.DynamicLibrary('my_lib.dylib') /// Sets the default dyLib to load for everything in this dart library
library interop;
import 'package:ffi_annotation/ffi_annotation.dart' as C;
part 'interop.g.dart';
/// Says hello
@C.Function('hello_world') // Annotation provides the function name in c header
void helloWorld() => _$helloWorld(); // all boilerplate code generated
/// Says hi to [name]
@C.Function('say_hi')
void sayHi(String name) => _$sayHi(name); // The generator will know how to map primitive types
@C.Function('distance_from', dyLib: 'utils.dylib') // The generator should be able to infer and map user-defined types
double distance(Coordinate from, Coordinate to) => _$distanceFrom(from, to);
class Coordinate extends C.Struct<Coordinate> {
double latitude;
double longitude;
factory Coordinate({double latitude, double longitude}) = _$Coordinate; // Forwards to the generated factory
@C.Function('coordinate_difference')
static Coordinate difference(Coordinate a, Coordinate b) => _$coordinateDifference(a, b);
}
Thoughts? |
I think the approach should be to read an .h-file to generate a .dart-file. Code generators with package:source_gen only work from .dart-file to .dart-file (often by matching on annotations) and uses the .part language feature to combine the generated .dart-file with the original .dart-file. Unfortunately, we do not have a package which aids parsing .h-files.
For code generation of .dart-files you can either use string concatenation or package:code_builder to build an AST.
(You could use package:build_runner to automate re-generating the .dart-file if/when the .h-file is changed, but I think that would be of later concern. First, a manually run generator would do the job.)
|
The dart-only approach I suggested tries to solve the boilerplate problem for dart bindings that are hand-written. It will generate the code that will do things like automatic conversion of dart This is the kind of boilerplate code that would be generated class _$Coordinate extends Coordinate{
factory _$Coordinate(double latitude, double longitude) {
final createCoordinatePointer = dylib
.lookup<ffi.NativeFunction<create_coordinate_func>>('create_coordinate');
final createCoordinate =
createCoordinatePointer.asFunction<CreateCoordinate>();
final coordinatePointer = createCoordinate(latitude, longitude);
return coordinate = coordinatePointer.load();
}
} A user would only have to do In this approach where inputs are hand-written bindings
In the approach where
A user of these bindings would prefer a fluent api like A generator that parses Thoughts? P.S. I read my own comment and it looks like I favor one approach over the other. This is not the case, I'm still very much in the discussion phase. |
@devkabiir Let's discuss this further in the issue dedicated to this: #35843. |
Let's accumulate here everything we want to have in Dart 2.6 that is still open:
Please just edit this post if you want to add more tasks or mark some as completed.
/cc @mraleph @mit-mit
The text was updated successfully, but these errors were encountered: