Anweisungen zur Verwendung von dart: ffi zum Aufrufen von C-Funktionen von Dart finden Sie auf der folgenden Seite.
Alle waren jedoch Beispiele für einfache Synchronisationsfunktionsaufrufe Ich werde als Erinnerung aufschreiben, wie der Rückruffunktionsaufruf implementiert wird. Wenn Sie Fehler oder bessere Möglichkeiten haben, lassen Sie es uns bitte wissen.
Es wurde keine Dokumentation gefunden. In dart-lang / sdk [Beispiel](https://github.com/dart-lang/sdk/blob/2.12.0-21.0. dev / samples / ffi / sample_ffi_functions_callbacks.dart) wurde gefunden, also habe ich darauf verwiesen.
Die Betriebsüberprüfungsumgebung ist wie folgt. Darüber hinaus haben wir den Betrieb auf Linux Desktop als Plattform von Flutter bestätigt.
$ 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)
Dieses Mal habe ich "qsort (3)" als Funktion gewählt, um die berühmte Rückruffunktion aufzurufen, die überall verwendet werden kann. Eigentlich denke ich, dass ich "qsort_r (3)" verwenden werde, aber da dies nicht der Hauptpunkt dieser Zeit ist, verwende ich "qsort (3)", um den Code einfach zu halten.
Hier ist ein Prototyp und eine Beschreibung von "qsort (3)" von man.
void qsort(void *base, size_t nmemb, size_t size,
int (*compar)(const void *, const void *));
[man qsort(3)] Die Funktion qsort () sortiert ein Array mit Elementen der Größe nmemb. Das Basisargument ist ein Zeiger auf den Anfang des Arrays. Die vergleichende Vergleichsfunktion ordnet den Inhalt des Arrays in aufsteigender Reihenfolge an (je höher der Wert, desto später). Das Argument der Vergleichsfunktion ist ein Zeiger auf die beiden zu vergleichenden Objekte.
Die Vergleichsfunktion ist 1) kleiner als Null, 2) Null, 3) kleiner als Null, je nachdem, ob das erste Argument 1) kleiner, 2) gleich oder 3) größer als das zweite Argument ist. Muss eine der größeren ganzen Zahlen zurückgeben. Wenn die Vergleichsergebnisse der beiden Elemente gleich sind, wird die Reihenfolge der beiden in der neu angeordneten Reihenfolge nicht angegeben.
Verwenden Sie dieses qsort (3)
, um das int-Array in aufsteigender Reihenfolge zu sortieren.
Wenn in C-Sprache implementiert, ist es wie folgt.
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
//Rückruffunktion
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;
}
Diesmal wird der gleiche Vorgang über dart: ffi aufgerufen.
Jetzt werde ich die Implementierung sofort in Dart veröffentlichen.
//Typdefinition
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>>);
//Rückruffunktion
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) {
//Dartliste in C-Array konvertieren
final dataPtr = intListToArray(data);
// qsort(3)Holen Sie sich den Handler für libc, der definiert
final libc = DynamicLibrary.open('libc.so.6');
//Holen Sie sich die Adresse des Symbols qsort von libc und konvertieren Sie es in die Dart-Funktion
final qsort =
libc.lookup<NativeFunction<NativeQsort>>('qsort').asFunction<Qsort>();
//Dart-Funktion im Vergleich zum C-Funktionszeiger konvertieren
Pointer<NativeFunction<NativeCompar>> pointer =
Pointer.fromFunction(compar, 0);
//libc qsort(3)Wird aufgerufen, indem das Array, die Anzahl der Elemente, die Elementgröße und der Funktionszeiger an übergeben werden
qsort(dataPtr, data.length, sizeOf<Int32>(), pointer);
//Konvertieren Sie das C-Array in die Dart-Liste
return arrayToIntList(dataPtr, data.length);
}
Der Verarbeitungsablauf wird als Kommentar beschrieben.
Der Punkt beim Übergeben der Dart-Funktion als Rückruffunktion ist Pointer # fromFunction. .. Mit dieser Methode können Sie eine Dart-Funktion in einen C-Funktionszeiger konvertieren. Wenn es offensichtlich ist, werden die Argumente automatisch gemarshallt.
Der Code, der im obigen Beispiel als Flutter-App fungiert, ist unten aufgeführt.
Andere Sprachbindungen haben viele Typkonvertierungen und sind unweigerlich lang in der Notation. Wenn Sie es ruhig lesen, entspricht es im Wesentlichen dem Umgang mit Funktionszeigern in der Sprache C.
Natürlich, wenn es tatsächlich in der Entwicklung, Fehlerbehandlung, Ressourcenverwaltung, Vermeidung subtiler typografischer Fehler verwendet wird, Einfallsreichtum, um die Anzahl der Kopien zu reduzieren, Bibliothekshandler und Symbole zwischenzuspeichern usw. Es gibt viele andere Dinge, über die man nachdenken muss, Wenn Sie durch die Typkonvertierung nicht verwirrt sind, können Sie sich das genauso vorstellen wie die native Entwicklung.
sdk/sample_ffi_functions_callbacks.dart at 2.12.0-21.0.dev · dart-lang/sdk
Beispiel für einen Rückruf mit dart: ffi in dart-lang / sdk
Der Code auf der nativen Seite lautet ffi_test_functions auf der Laufzeitseite
samples/ffi at master · dart-lang/samples --ffi sample von dart-lang / samples
ffi_tool | Dart Package --Paket zum automatischen Generieren von Code für ffi-Aufrufe
Rückruf wird nicht erwähnt, aber es war sehr hilfreich für mich, die Geschichte von FFI auf leicht verständliche Weise zusammenzufassen.
Recommended Posts