Downcall Handles
Native Funktionen aufrufen
Downcall Handles ist eine kostenlose Java Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Java Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Native Funktionen aufrufen
Ein Downcall ist ein Aufruf aus Java in nativen Code hinein. FFM stellt jede native Funktion als ein aus einem Linker erstelltes MethodHandle dar.
In dieser Lektion erfahren Sie, wie Sie eine C-Funktion finden, beschreiben und aufrufen.
Der native Linker
Linker.nativeLinker() gibt den Linker für die aktuell ausgeführte Plattform zurück. Er kennt die C-Aufrufkonvention und kann Handles für native Funktionen erzeugen.
import java.lang.foreign.Linker;
public class Main {
public static void main(String[] args) {
Linker linker = Linker.nativeLinker();
System.out.println("Got native linker: " + linker);
}
}Ein Symbol finden
Sie benötigen die Adresse der Funktion. linker.defaultLookup() durchsucht die Standard-C-Bibliothek; SymbolLookup.libraryLookup(name, arena) lädt eine bestimmte gemeinsam genutzte Bibliothek.
import java.lang.foreign.*;
public class Main {
public static void main(String[] args) {
Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();
MemorySegment addr = stdlib.find("strlen").orElseThrow();
System.out.println("strlen address found: " + addr);
}
}Die Signatur beschreiben
Ein FunctionDescriptor beschreibt die C-Signatur anhand von Layouts. Bei size_t strlen(const char*) ist der Rückgabewert ein long und das Argument ein Zeiger (ADDRESS).
import java.lang.foreign.*;
public class Main {
public static void main(String[] args) {
FunctionDescriptor desc = FunctionDescriptor.of(
ValueLayout.JAVA_LONG, // return: size_t
ValueLayout.ADDRESS); // arg: const char*
System.out.println("Descriptor: " + desc);
}
}Das Handle erstellen
Kombinieren Sie das Symbol und den Deskriptor mit downcallHandle, um ein MethodHandle zu erhalten, das Sie wie jede Java-Methode aufrufen können.
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
public class Main {
public static void main(String[] args) {
Linker linker = Linker.nativeLinker();
MethodHandle strlen = linker.downcallHandle(
linker.defaultLookup().find("strlen").orElseThrow(),
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS));
System.out.println("Handle ready: " + strlen.type());
}
}Die Funktion aufrufen
Um strlen aufzurufen, übergeben Sie einen Zeiger auf einen nativen String. Reservieren Sie den String in einer Arena und rufen Sie anschließend das Handle mit invoke auf. Das Ergebnis wird als Java-long zurückgegeben.
import java.lang.foreign.*;
import java.lang.invoke.MethodHandle;
public class Main {
public static void main(String[] args) throws Throwable {
Linker linker = Linker.nativeLinker();
MethodHandle strlen = linker.downcallHandle(
linker.defaultLookup().find("strlen").orElseThrow(),
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS));
try (Arena arena = Arena.ofConfined()) {
MemorySegment str = arena.allocateUtf8String("Hello, FFM");
long len = (long) strlen.invoke(str);
System.out.println("Length = " + len);
}
}
}Typen abbilden
Jeder C-Typ wird auf ein Layout abgebildet:
intaufValueLayout.JAVA_INTlong/size_taufJAVA_LONGdoubleaufJAVA_DOUBLE- jeder Zeiger auf
ADDRESS
Die korrekte Zuordnung ist entscheidend, andernfalls werden Daten durch den Aufruf beschädigt.
Funktionen, die Zeiger zurückgeben
Wenn eine C-Funktion einen Zeiger zurückgibt, liefert das Handle ein MemorySegment der Länge null. Um über dessen Anfang hinaus zu lesen, müssen Sie es mit reinterpret(byteSize) auf die richtige Größe neu interpretieren.
Viele Argumente übergeben
FunctionDescriptor.of(returnLayout, arg1, arg2, ...) listet die Argumente in der richtigen Reihenfolge auf. Für eine void-Funktion verwenden Sie FunctionDescriptor.ofVoid(args...) ohne Layout für den Rückgabewert.
import java.lang.foreign.*;
public class Main {
public static void main(String[] args) {
// int (*)(const char*, int)
FunctionDescriptor two = FunctionDescriptor.of(
ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.JAVA_INT);
// void (*)(int)
FunctionDescriptor noReturn = FunctionDescriptor.ofVoid(ValueLayout.JAVA_INT);
System.out.println(two + " / " + noReturn);
}
}Fehler im Handle mit throws behandeln
Da MethodHandle.invoke throws Throwable deklariert, muss Ihre aufrufende Methode die Ausnahme behandeln oder deklarieren. Deshalb deklarieren die Beispiele throws Throwable.
Das Handle zwischenspeichern
Das Erstellen eines Downcall-Handles ist relativ aufwendig. Erstellen Sie es daher einmal und verwenden Sie es wieder. Ein häufig verwendetes Muster besteht darin, das Handle während der Klasseninitialisierung in einem Feld static final zu binden und es viele Male aufzurufen.
Das Handle selbst ist für gleichzeitige Aufrufe durch mehrere Threads thread-sicher.
Kurzer Test
Rufen Sie sich ins Gedächtnis, wie ein C-Zeigerargument beschrieben wird.
Zusammenfassung
Sie haben gelernt, native Funktionen aufzurufen:
Linker.nativeLinker()zusammen mit einemSymbolLookup, um Symbole zu findenFunctionDescriptorbeschreibt die Signatur anhand von LayoutsdowncallHandleliefert einMethodHandle, das Sie mitinvokeaufrufen- Zeiger werden auf
ADDRESSabgebildet;invokelöstThrowableaus
Als Nächstes: komplexe native Daten mit Layouts und Strukturen beschreiben.
Häufig gestellte Fragen
Ist die Lektion „Downcall Handles“ kostenlos?
Ja — der vollständige Text von „Downcall Handles“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Java Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Java Academy-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Downcall Handles“?
Native Funktionen aufrufen Du übst Java Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Java Academy zu starten?
Keine Vorkenntnisse erforderlich. Java Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.
Wie lange dauert die Lektion „Downcall Handles“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Java Academy-Lektion Code schreiben und ausführen?
Ja. Jede Java Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Warum FFM statt JNI
- MemorySegment und Arena
- Downcall Handles
- Layouts und Structs