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

3,608

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
Share:
3,608
kakyo
Author by

kakyo

The more you learn, the more you hesitate.

Updated on December 18, 2022

Comments

  • kakyo
    kakyo over 1 year

    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?