c++flutterdartlanguage-interoperability

dart/flutter: getting data array from C/C++ using ffi?


The official flutter tutorial on C/C++ interop through ffi only touches on calling a C++ function and getting a single return value.

Goal

What if I have a data buffer created on C/C++ side, but want to deliver to dart/flutter-side to show?

Problem

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.

Code

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

Question

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");

======

Old Question (you can skip this)

Problem

It's unclear to me how to retrieve this kind of vector data from C/C++ by dart/flutter.

Possible solutions

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.

Option #1: Networking

I could do network through TCP sockets. But I'm reluctant to go there if there are easier solutions.

Option #2: file I/O

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?


Solution

  • 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