Vous trouverez des instructions sur l'utilisation de dart: ffi pour appeler des fonctions C depuis Dart sur la page suivante.
Cependant, tous étaient des exemples d'appels de fonction de synchronisation simples, donc J'écrirai comment implémenter l'appel de la fonction de rappel comme rappel. Si vous avez des erreurs ou de meilleurs moyens, veuillez nous en informer
Aucune documentation n'a été trouvée, Exemple Dans dart-lang / sdk. dev / samples / ffi / sample_ffi_functions_callbacks.dart) a été trouvé, alors j'y ai fait référence.
L'environnement de vérification de fonctionnement est le suivant. De plus, nous avons confirmé le fonctionnement sur Linux Desktop en tant que plate-forme de Flutter.
$ uname -a
Linux chama 5.5.8 #1 SMP Sat Mar 7 22:29:22 JST 2020 x86_64 x86_64 x86_64 GNU/Linux
$ lsb_release -d
Description: Ubuntu 18.04.5 LTS
$ flutter --version
Flutter 1.24.0-8.0.pre.117 • channel master • https://github.com/flutter/flutter
Framework • revision 8cb2665118 (8 hours ago) • 2020-11-06 16:02:19 +0800
Engine • revision 0693ee04d1
Tools • Dart 2.12.0 (build 2.12.0-21.0.dev)
Cette fois, j'ai choisi qsort (3)
comme fonction pour appeler la fameuse fonction de rappel qui peut être utilisée n'importe où.
En fait, je pense que j'utiliserai qsort_r (3)
, mais comme ce n'est pas le point principal de cette fois, j'utilise qsort (3)
pour garder le code simple.
Voici un prototype et une description de qsort (3)
de man.
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
[man qsort(3)] La fonction qsort () trie un tableau avec des éléments de taille nmemb size. L'argument de base est un pointeur vers le début du tableau. La fonction de comparaison par point de comparaison organise le contenu du tableau dans l'ordre croissant (plus la valeur est élevée, plus tard). L'argument de la fonction de comparaison est un pointeur vers les deux objets comparés.
La fonction de comparaison est 1) inférieure à zéro, 2) zéro, 3) inférieure à zéro, selon que le premier argument est 1) inférieur, 2) égal ou 3) supérieur au deuxième argument. Doit retourner l'un des plus grands entiers. Lorsque les résultats de comparaison des deux éléments sont égaux, l'ordre des deux n'est pas spécifié dans la séquence réorganisée.
Utilisez ce qsort (3)
pour trier le tableau int par ordre croissant.
S'il est implémenté en langage C, c'est comme suit.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
//fonction de rappel
static int compar(const void* rhs_ptr, const void* lhs_ptr) {
int32_t rhs = *(int32_t*)rhs_ptr;
int32_t lhs = *(int32_t*)lhs_ptr;
if (rhs > lhs) {
return 1;
} else if (rhs < lhs) {
return -1;
} else {
return 0;
}
}
int main(void) {
int32_t array[] = {1, 5, -10, 3, 9, 8, 7, 13};
qsort(array, sizeof(array) / sizeof(array[0]), sizeof(array[0]), compar);
for (uint32_t i = 0; i < sizeof(array) / sizeof(array[0]); i++) {
printf("%d\n", array[i]);
}
return 0;
}
Cette fois, le même processus est appelé via dart: ffi.
qsort (3)
depuis DartMaintenant, je publierai immédiatement l'implémentation dans Dart.
//Définition du type
typedef NativeCompar = Int32 Function(Pointer<Int32>, Pointer<Int32>);
typedef NativeQsort = Void Function(
Pointer<Int32>, Uint64, Uint64, Pointer<NativeFunction<NativeCompar>>);
typedef Qsort = void Function(
Pointer<Int32>, int, int, Pointer<NativeFunction<NativeCompar>>);
//fonction de rappel
int compar(Pointer<Int32> rhsPtr, Pointer<Int32> lhsPtr) {
final rhs = rhsPtr.value;
final lhs = lhsPtr.value;
if (rhs > lhs) {
return 1;
} else if (rhs < lhs) {
return -1;
} else {
return 0;
}
}
List<int> qsort(final List<int> data, _compar) {
//Convertir la liste de fléchettes en tableau C
final dataPtr = intListToArray(data);
// qsort(3)Obtenez le gestionnaire de la libc qui définit
final libc = DynamicLibrary.open('libc.so.6');
//Récupérez l'adresse du symbole qsort depuis la libc et convertissez-la en fonction Dart
final qsort =
libc.lookup<NativeFunction<NativeQsort>>('qsort').asFunction<Qsort>();
//Convertir la fonction Dart par rapport au pointeur de fonction C
Pointer<NativeFunction<NativeCompar>> pointer =
Pointer.fromFunction(compar, 0);
//libc qsort(3)Appelé en passant le tableau, le nombre d'éléments, la taille de l'élément et le pointeur de fonction à
qsort(dataPtr, data.length, sizeOf<Int32>(), pointer);
//Convertir un tableau C en liste de fléchettes
return arrayToIntList(dataPtr, data.length);
}
Le flux de traitement est décrit sous forme de commentaire.
Le point lors du passage de la fonction Dart en tant que fonction de rappel est Pointer # fromFunction. .. Vous pouvez convertir une fonction Dart en un pointeur de fonction C avec cette méthode. Quant aux arguments, ceux qui sont évidents seront automatiquement rassemblés.
Le code qui fonctionne comme l'application Flutter dans l'exemple ci-dessus est ci-dessous.
D'autres liaisons de langage ont beaucoup de conversions de type et sont forcément longues en notation Si vous le lisez calmement, c'est essentiellement la même chose que la gestion des pointeurs de fonction en langage C.
Bien sûr, lors de son utilisation réelle en développement, gestion des erreurs, gestion des ressources, prévention des erreurs typographiques subtiles, Ingéniosité pour réduire le nombre de copies, mise en cache des gestionnaires de bibliothèques et des symboles, etc. Il y a beaucoup d'autres choses à penser, Si vous n'êtes pas confus par la conversion de type, je pense que vous pouvez y penser de la même manière que le développement natif.
sdk/sample_ffi_functions_callbacks.dart at 2.12.0-21.0.dev · dart-lang/sdk
Exemple de rappel avec dart: ffi dans dart-lang / sdk
Le code du côté natif est ffi_test_functions du côté de l'exécution
samples/ffi at master · dart-lang/samples --ffi échantillon de dart-lang / samples
ffi_tool | Dart Package --Package pour générer automatiquement du code pour les appels ffi
Il n'y a aucune mention de rappel, mais il m'a été très utile de résumer l'histoire de FFI d'une manière facile à comprendre.
Recommended Posts