Handle Downcall
Panggil fungsi native.
Handle Downcall adalah pelajaran Java Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Java Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Java Academy mencakup 4 pelajaran total.
Memanggil Fungsi Natif
Panggilan ke bawah adalah pemanggilan dari Java ke dalam kode natif. FFM merepresentasikan setiap fungsi natif sebagai MethodHandle yang dibuat dari sebuah Linker.
Pelajaran ini membahas cara menemukan, mendeskripsikan, dan memanggil fungsi C.
Penghubung Natif
Linker.nativeLinker() mengembalikan penghubung untuk platform yang sedang dijalankan. Penghubung ini mengetahui konvensi pemanggilan C dan dapat menghasilkan referensi ke fungsi natif.
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);
}
}Menemukan Simbol
Anda memerlukan alamat fungsi tersebut. linker.defaultLookup() mencari di pustaka C standar; SymbolLookup.libraryLookup(name, arena) memuat pustaka bersama tertentu.
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);
}
}Mendeskripsikan Tanda Tangan
FunctionDescriptor mendeskripsikan tanda tangan C berdasarkan tata letak. Untuk size_t strlen(const char*), nilai kembaliannya berupa long dan argumennya berupa penunjuk (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);
}
}Membuat Referensi
Gabungkan simbol dan deskriptor dengan downcallHandle untuk mendapatkan MethodHandle yang dapat Anda panggil seperti metode Java apa pun.
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());
}
}Memanggil Fungsi
Untuk memanggil strlen, Anda memberikan penunjuk ke string natif. Alokasikan string tersebut dalam arena, lalu panggil referensinya dengan invoke. Hasilnya dikembalikan sebagai long Java.
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);
}
}
}Memetakan Tipe
Setiap tipe C dipetakan ke sebuah tata letak:
intkeValueLayout.JAVA_INTlong/size_tkeJAVA_LONGdoublekeJAVA_DOUBLE- penunjuk apa pun ke
ADDRESS
Mendapatkan pemetaan ini dengan benar sangat penting; jika tidak, pemanggilan akan merusak data.
Fungsi yang Mengembalikan Penunjuk
Ketika fungsi C mengembalikan penunjuk, referensi tersebut mengembalikan MemorySegment dengan panjang nol. Untuk membaca melewati awalnya, Anda harus menafsirkannya ulang ke ukuran yang benar dengan reinterpret(byteSize).
Meneruskan Banyak Argumen
FunctionDescriptor.of(returnLayout, arg1, arg2, ...) mencantumkan argumen sesuai urutannya. Untuk fungsi void, gunakan FunctionDescriptor.ofVoid(args...) tanpa tata letak nilai kembali.
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);
}
}Menangani Kesalahan dengan throws
Karena MethodHandle.invoke mendeklarasikan throws Throwable, metode pemanggil Anda harus menanganinya atau mendeklarasikannya. Itulah alasan contoh-contoh tersebut mendeklarasikan throws Throwable.
Menyimpan Referensi dalam Cache
Membuat referensi panggilan ke bawah relatif mahal, jadi lakukan sekali lalu gunakan kembali. Pola yang umum adalah mengikat referensi tersebut ke dalam bidang static final selama inisialisasi kelas, lalu memanggilnya berkali-kali.
Referensi itu sendiri aman dipanggil secara bersamaan dari banyak utas.
Pemeriksaan Singkat
Ingat kembali cara mendeskripsikan argumen penunjuk C.
Ringkasan
Anda telah mempelajari cara memanggil fungsi natif:
Linker.nativeLinker()bersamaSymbolLookupuntuk menemukan simbolFunctionDescriptormendeskripsikan tanda tangan dengan tata letakdowncallHandlemenghasilkanMethodHandleyang Anda panggil denganinvoke- Penunjuk dipetakan ke
ADDRESS;invokememunculkanThrowable
Selanjutnya: mendeskripsikan data natif yang kompleks dengan tata letak dan struktur.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Handle Downcall” gratis?
Ya — teks lengkap “Handle Downcall” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Java Academy, upgrade ke CoddyKit PRO. Kursus Java Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Handle Downcall”?
Panggil fungsi native. Kamu berlatih Java Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Java Academy?
Tidak diperlukan pengalaman sebelumnya. Java Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Handle Downcall” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Java Academy ini?
Ya. Setiap pelajaran Java Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.