The official flutter tutorial on C/C++ interop through ffi only touches on calling a C++ function and getting a single return value.
What if I have a data buffer created on C/C++ side, but want to deliver to dart/flutter-side to show?
With @MilesBudnek 's tip, I'm testing Dart's FFI by trying to have safe memory deallocation from Dart to C/C++. The test reuses the official struct sample .
I could get the Array as a dart Pointer
, but it's unclear to me how to iterate the array as a collection easily.
I'm implementing a Dart-side C array binding like this:
In struct.h
struct Array
{
int* array;
int len;
};
and a pair of simple allocation/deallocation test functions:
struct Array* get_array();
int del_array(struct Array* arr);
Then on Dart side in structs.dart
:
typedef get_array_func = Pointer<Array> Function();
typedef del_array_func = void Function(int arrAddress);
...
final getArrayPointer = dylib.lookup<NativeFunction<get_array_func>>('get_array');
final getArray = getArrayPointer.asFunction<get_array_func>();
final arrayPointer = getArray();
final array = arrayPointer.ref.array;
print('array.array: $array');
This gives me the print out
array.array: Pointer<Int32>: address=0x7fb0a5900000
Can I convert the array pointer to a List
easily? Something like:
final array = arrayPointer.ref.array.toList();
array.forEach(index, elem) => print("array[$idx]: $elem");
It's unclear to me how to retrieve this kind of vector data from C/C++ by dart/flutter.
More importantly, how to push data from C++ side from various threads? If there is no builtin support, off the top of my head I'd need to implement some communication schemes.
I could do network through TCP sockets. But I'm reluctant to go there if there are easier solutions.
Write data to file with C/C++, and let dart/flutter poll on the file and stream data over. This is not realtime friendly.
So, are there better options?
Solved it.
According to this issue, the API asTypedList is the way to go.
Here is the code that works for me
final getArrayPointer = dylib.lookup<NativeFunction<get_array_func>>('get_array');
final getArray = getArrayPointer.asFunction<get_array_func>();
final arrayPointer = getArray();
final arr = arrayPointer.ref.arr;
print('array.array: $arr');
final arrReal = arr.asTypedList(10);
final arrType = arrReal.runtimeType;
print('arrReal: $arrReal, $arrType');
arrReal.forEach((elem) => print("array: $elem"));
This gives me:
array.array: Pointer<Int32>: address=0x7f9eebb02870
arrReal: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], Int32List
array: 0
array: 1
array: 2
array: 3
array: 4
array: 5
array: 6
array: 7
array: 8
array: 9