0Pricing
Java Academy · Pelajaran

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:

  • int ke ValueLayout.JAVA_INT
  • long/size_t ke JAVA_LONG
  • double ke JAVA_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() bersama SymbolLookup untuk menemukan simbol
  • FunctionDescriptor mendeskripsikan tanda tangan dengan tata letak
  • downcallHandle menghasilkan MethodHandle yang Anda panggil dengan invoke
  • Penunjuk dipetakan ke ADDRESS; invoke memunculkan Throwable

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.

Semua pelajaran dalam kursus ini

  1. Mengapa FFM, bukan JNI
  2. MemorySegment dan Arena
  3. Handle Downcall
  4. Layout dan Struct
← Kembali ke Java Academy