Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 393
kakyo Avatar asked Mar 27 '20 03:03

kakyo


1 Answers

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
like image 100
kakyo Avatar answered Nov 05 '22 14:11

kakyo