-
Notifications
You must be signed in to change notification settings - Fork 32
[ffi] Helpers for interacting with C data #17
Comments
Does external contribution welcome ? |
In general, yes, but at this stage the FFI interface is very unstable, so I think it would be premature to build a library on top of it. However, feature requests are still welcome since they will inform our API design. |
We could expose an iterator on extension StructIterable<T extends Struct> on Pointer<T> {
Iterable<T> asIterable(int length) => _StructIterable(this, length);
}
class _StructIterable<T extends Struct> extends IterableBase<T>
implements Iterable<T> {
final Iterator<T> iterator;
_StructIterable(Pointer<T> pointer, int length)
: iterator = _StructIterator(pointer, length);
}
class _StructIterator<T extends Struct> implements Iterator<T> {
final Pointer<T> pointer;
int i = -1;
int length;
_StructIterator(this.pointer, this.length);
bool moveNext() {
if (i + 1 >= length) {
return false;
}
i++;
return true;
}
T get current => pointer[i];
} Since Any thoughts @mkustermann @lrhn? |
Tangential: We prefer to keep the Small detail: The example above uses one iterator per iterable, which is not quite correct I believe, because it must be possible to iterate over an iterable multiple times, e.g. final Iterable iterable = foo.asIterable(10);
for (final value in iterable) print(value);
for (final value in iterable) print(value); In the example the second loop would re-use the same iterator as the first loop and probably run 0 times. Otherwise I think it's reasonable. Though one has to be careful, as always, to manage the memory manually. |
Yes, I was thinking |
As discussed with @lrhn offline: The interface should be a |
Hey, I was just wondering how With the earlier API, I just used: var ptr = ffi.Pointer<Struct>.allocate();
ptr.store(struct); But I can't find a way to do this with the new Considering how commonplace |
@devxpy We currently do not support storing a whole struct by value. Assuming that is a Pointer to a struct, in order to allocate a pointer you use allocate from this package, just pin it to the latest dev version. (We'll release a new version when Dart 2.6 is released.) In this package the signature would be Pointer<Struct> struct; // from somewhere
final ptr = allocate<Pointer<Struct>>();
ptr.value = struct; |
Sorry for not filling in these details earlier.
To elaborate, this is what I wanted - class FPDF_LIBRARY_CONFIG extends Struct {
...
}
FPDF_LIBRARY_CONFIG config = FPDF_LIBRARY_CONFIG();
Pointer<FPDF_LIBRARY_CONFIG> ptr = allocate<FPDF_LIBRARY_CONFIG>();
ptr.value = config; But that results in the following error -
I want this because the underlying library expects // fpdfview.h
FPDF_EXPORT void FPDF_CALLCONV FPDF_InitLibraryWithConfig(const FPDF_LIBRARY_CONFIG* config); It would be sweet FPDF_LIBRARY_CONFIG config = FPDF_LIBRARY_CONFIG();
Pointer<FPDF_LIBRARY_CONFIG> ptr = allocate<FPDF_LIBRARY_CONFIG>([config]); This could also make allocating Lists easy - Pointer<Int32> ptr = allocate<Int32>([1, 2, 3, 4, 5]); |
We do not support having C-values in the Dart heap (yet). So you want to allocate the C-memory first, and then write to the individual fields. However, nothing is stopping you from writing a constructor that does exactly that. class Coordinate extends Struct {
@Double()
double x;
@Double()
double y;
Pointer<Coordinate> next;
factory Coordinate.allocate(double x, double y, Pointer<Coordinate> next) {
return allocate<Coordinate>().ref
..x = x
..y = y
..next = next;
}
} See our samples. For your example Pointer<FPDF_LIBRARY_CONFIG> ptr = allocate<FPDF_LIBRARY_CONFIG>();
// ptr.field1 = value1;
// ptr.field2 = value2;
// ...
// (all of the above could be put in a FPDF_LIBRARY_CONFIG.allocate constructor.)
// call FPDF_InitLibraryWithConfig with ptr. For allocating lists you could write your own helpers: Pointer<Int32> allocateList(List<int> values) {
final ptr = allocate<Int32>(count: values.length);
for (int i = 0; i < values.length; i++) {
ptr[i] = values[i];
}
return ptr;
} |
The sample code got moved into this package https://github.com/dart-lang/ffi/blob/master/lib/src/utf8.dart I see that the Utf16 variant is missing some methods, but they should be similar to the Utf8 ones. P.S. feel free to post your questions on the mailing list dart-ffi@googlegroups.com or open separate GitHub issues. |
Any progress recently? |
Further String work is tracked in dart-lang/sdk#39787. We do not have any plans for any iteration support beyond Closing this issue. Feel free to request more features or send pull requests. |
There are a number of helpful facilities which can be built on top of the FFI foundation and should probably be included in
dart:ffi
, for example:CString
: wrapper for strings allocated in CCArray<T>
: wrapper for arrays allocated in C, compatible with List, Iterable, TypedData, etc. typesSuggestions for others are welcome!
The text was updated successfully, but these errors were encountered: