Pemegang Downcall
Panggil fungsi natif
Pemegang Downcall ialah pelajaran Java Academy percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Java Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Java Academy merangkumi sejumlah 4 pelajaran.
Memanggil Fungsi Natif
Panggilan ke bawah ialah panggilan daripada Java ke dalam kod natif. FFM mewakili setiap fungsi natif sebagai MethodHandle yang dibina daripada Linker.
Pelajaran ini menerangkan cara mencari, menghuraikan dan memanggil fungsi C.
Pemaut Natif
Linker.nativeLinker() mengembalikan pemaut untuk platform yang sedang digunakan. Ia mengetahui konvensyen panggilan C dan boleh menghasilkan pemegang kepada 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);
}
}Mencari Simbol
Anda memerlukan alamat fungsi tersebut. linker.defaultLookup() mencari dalam pustaka C piawai; SymbolLookup.libraryLookup(name, arena) memuatkan pustaka dikongsi 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);
}
}Menghuraikan Tandatangan
FunctionDescriptor menghuraikan tandatangan C dari segi susun atur. Untuk size_t strlen(const char*), nilai pulangannya ialah integer panjang dan hujahnya ialah penuding (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);
}
}Membina Pemegang
Gabungkan simbol dan deskriptor dengan downcallHandle untuk mendapatkan MethodHandle yang boleh anda panggil seperti mana-mana kaedah Java.
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 penuding kepada rentetan natif. Peruntukkan rentetan itu dalam arena, kemudian panggil pemegang dengan invoke. Hasilnya dikembalikan sebagai integer panjang 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 Jenis
Setiap jenis C dipetakan kepada satu susun atur:
intkepadaValueLayout.JAVA_INTlong/size_tkepadaJAVA_LONGdoublekepadaJAVA_DOUBLE- sebarang penuding kepada
ADDRESS
Pemetaan ini mesti dilakukan dengan betul; jika tidak, panggilan akan merosakkan data.
Fungsi yang Mengembalikan Penuding
Apabila fungsi C mengembalikan penuding, pemegang tersebut mengembalikan MemorySegment yang panjangnya sifar. Untuk membaca melepasi permulaannya, anda mesti mentafsirkannya semula kepada saiz yang betul dengan reinterpret(byteSize).
Menghantar Banyak Hujah
FunctionDescriptor.of(returnLayout, arg1, arg2, ...) menyenaraikan hujah mengikut tertib. Untuk fungsi void, gunakan FunctionDescriptor.ofVoid(args...) tanpa susun atur pulangan.
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 Ralat dengan Pernyataan Lontaran
Oleh sebab MethodHandle.invoke mengisytiharkan throws Throwable, kaedah pemanggil mesti menanganinya atau mengisytiharkannya. Sebab itulah contoh mengisytiharkan throws Throwable.
Menyimpan Pemegang dalam Cache
Membina pemegang panggilan ke bawah agak mahal, jadi lakukan sekali dan gunakannya semula. Corak yang biasa ialah mengikat pemegang pada medan static final semasa pemulaan kelas dan memanggilnya berkali-kali.
Pemegang itu sendiri selamat dipanggil secara serentak oleh berbilang utas.
Semakan Ringkas
Ingat kembali cara hujah penuding C dihuraikan.
Imbas Kembali
Anda telah mempelajari cara memanggil fungsi natif:
Linker.nativeLinker()bersamaSymbolLookupuntuk mencari simbolFunctionDescriptormenghuraikan tandatangan dengan susun aturdowncallHandlemenghasilkanMethodHandleyang andainvoke- Penuding dipetakan kepada
ADDRESS;invokemenghasilkanThrowable
Seterusnya: menghuraikan data natif yang kompleks dengan susun atur dan struktur.
Pelajari Java dengan tutor kecerdasan buatan — percuma
Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.
- Kursus
- 104
- Pelajaran
- 374
Soalan Lazim
Adakah pelajaran “Pemegang Downcall” percuma?
Ya — teks penuh “Pemegang Downcall” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Java Academy, tingkat taraf kepada CoddyKit PRO. Kursus Java Academy merangkumi sejumlah 4 pelajaran.
Apakah yang akan saya pelajari dalam “Pemegang Downcall”?
Panggil fungsi natif Anda berlatih Java Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.
Adakah saya memerlukan pengalaman untuk memulakan Java Academy?
Tiada pengalaman terdahulu diperlukan. Pembelajaran Java Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.
Berapa lamakah pelajaran “Pemegang Downcall” diambil?
Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.
Bolehkah saya menulis dan menjalankan kod dalam pelajaran Java Academy ini?
Ya. Setiap pelajaran Java Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.