6 votes

dart/flutter : récupération d'un tableau de données depuis C/C++ en utilisant ffi ?

Le tutoriel officiel de flutter sur l'interopérabilité C/C++ grâce à ffi n'aborde que l'appel d'une fonction C++ et l'obtention d'une seule valeur de retour.

Objectif

Que se passe-t-il si j'ai créé un tampon de données du côté C/C++, mais que je veux le transmettre au côté fléchette/flutter pour l'afficher ?

Problème

Avec le conseil de @MilesBudnek, je teste la FFI de Dart en essayant d'avoir une désallocation de mémoire sûre de Dart vers C/C++. Le test réutilise l'échantillon officiel de la structure .

Je pourrais avoir l'Array comme une fléchette. Pointer mais je ne vois pas comment itérer facilement le tableau comme une collection.

Code

J'implémente une liaison de tableau C côté Dart comme ceci :

En struct.h

struct Array
{
    int* array;
    int len;
};

et une paire de fonctions de test simples d'allocation/désallocation :

struct Array* get_array();
int del_array(struct Array* arr);

Puis sur le côté Dart dans 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');

Cela me donne l'impression

array.array: Pointer<Int32>: address=0x7fb0a5900000

Question

Puis-je convertir le pointeur de tableau en un List facilement ? Quelque chose comme :

final array = arrayPointer.ref.array.toList();
array.forEach(index, elem) => print("array[$idx]: $elem");

\======

Ancienne question (vous pouvez sauter cette étape)

Problème

Je ne vois pas très bien comment récupérer ce type de données vectorielles en C/C++ par dart/flutter.

Solutions possibles

Plus important encore, comment pousser les données du côté C++ à partir de différents threads ? S'il n'y a pas de support intégré, il me faudrait, de mémoire, mettre en place des schémas de communication.

Option n° 1 : mise en réseau

Je pourrais faire du réseau à travers des sockets TCP. Mais je suis réticent à aller jusque là s'il existe des solutions plus simples.

Option n° 2 : E/S de fichiers

Écrire des données dans un fichier avec C/C++, et laisser dart/flutter interroger le fichier et transmettre les données. Cette méthode n'est pas adaptée au temps réel.

Alors, y a-t-il de meilleures options ?

10voto

kakyo Points 948

Je l'ai résolu.

Según cette question l'API asTypedList est la voie à suivre.

Voici le code qui fonctionne pour moi

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

Cela me donne :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X