Learn · concepts

JNI Nedir? Modcular İçin Java Yerel Arayüzü

JNI (Java Yerel Arayüzü), JVM'den C/C++ kodunu çağırmak ve geri çağırmak için Java'nın yerleşik köprüsüdür. Minecraft modlarının yerel bir kütüphane yüklemesinin standart yoludur.

TRtrolPublished 5 min read

JNI'yi basitçe anlatınca ne demektir?

JNI (Java Native Interface), Java'nın iki dünyayı birbirine bağlayan kısmıdır: JVM üzerindeki yönetilen bytecode ve C veya C++ ile yazılmış derlenmiş makine kodu. Bir metot native anahtar kelimesini alır ve gövdesi olmaz, çalışma zamanında JVM bu metodu yüklenen yerel kütüphanedeki eşleşen bir fonksiyona bağlar. Oradan her iki taraf da argümanları ve dönüş değerlerini alışverişi yapar.

Sınır tek yönlü değildir. Yerel fonksiyon bir JNIEnv işaretçisi alır ve bu işaretçi Java'ya geri dönmek için bir geçittir: Java alanlarını okuma ve yazma, Java metotlarını çağırma, nesneler oluşturma ve istisnalar yükseltme için çağrıları açığa çıkarır. Böylece Java'nın dışarı çağırmasına izin veren aynı köprü, C'nin içeri çağırmasına da izin verir.

Bir Minecraft modunun veya istemcisinin neden yerel koda dokunması gerekir?

Çoğu Java JNI'ye ihtiyaç duymaz. Bir mod, JVM'nin tek başına işi yapamadığı durumlarda ona başvurur; genellikle grafikler, ses, işletim sistemi entegrasyonu veya hızlı olması gereken bir rutin. Yerel kütüphane ağır işleri yapar ve JNI onu yüklemenin ve çağırmanın standart yoludur.

Kanıtlanmış bir C kütüphanesini yeniden kullanın

Olgun, yerli bir kod tabanı zaten bu sorunu çözüyor. Java'da yeniden yazmak boşa bir çaba olur, bu yüzden mod buna bağlanıyor.

İşletim sistemine ulaş

Bazı platform özelliklerinin saf Java API'si bulunmamaktadır. Onlara ulaşmanın tek yolu yerel bir çağrı olmaktadır.

Hızlı bir yol aç

Sıkı bir sayısal veya düşük seviyeli rutin, JVM üzerinde bytecode olarak çalışırsa, derlenmiş yerel kod olarak çalışırsa daha hızlı çalışabilir.

Sürücü donanımını ve sürücüleri

JNI, Java tarafına açtığı yerel kütüphanelerin arkasında genellikle işleme, ses ve cihaz erişimi bulunur.

JNI çağrısı uçtan uca nasıl çalışır?

Akış, her platformda aynıdır: yöntemi Java'da bildirin, eşleşen bir C fonksiyonunu paylaşılan bir kütüphaneye derleyin, çalışma zamanında yükleyin, JVM'nin bunları ada göre bağlamasına izin verin ve ardından geçiş yapın. Fonksiyon adları, JVM'nin bunları çözebilmesi için sabit bir kalıba uyar ve oluşturulan bir başlık uygulanacak kesin imzayı belirtir.

AdımOlanlar
BildirBir Java yöntemi native anahtar kelimesiyle yazılır ve Java tarafında boş bırakılır.
OluşturBir C veya C++ fonksiyonu, Windows'ta .dll, Linux'ta .so, macOS'ta .dylib gibi paylaşılan bir kütüphaneye derlenir.
YükleJava, program çalışırken kütüphaneyi yüklemek için System.loadLibrary'yi çağırır.
BağlaJVM, her native yöntemini, adla bozulmuş bir imza aracılığıyla C fonksiyonuna eşler.
ÇağırJava yöntemi çağırır; kontrol yerel koda geçer ve bir sonuçla geri döner.

JNI size neye mal oluyor?

JNI güçlüdür ve keskin kenarları vardır. Yerel kod, JVM'nin güvenlik ağı dışında çalıştığı için, oradaki bir hata yakalanabilir bir istisna fırlatmak yerine tüm süreci çökertir. Yerel tarafın ayırdığı bellek çöp toplayıcı tarafından görünmez, bu nedenle elle serbest bırakılmadıkça sızıntılar birikir. Her geçiş ek yük getirir ve bu da sınırın içinden sık bir döngü içinde çağırmayı pahalı hale getirir. Ve yerel derlemeler platforma özeldir: bir Windows .dll dosyası, ayrı bir derleme olmadan Linux'ta yüklenemez.

Neler aldığı

  • Mevcut C ve C++ kütüphanelerine doğrudan erişim
  • JVM'nin ulaşamadığı işletim sistemi ve donanım özelliklerine bir yol
  • En çok kullanılan rutinler için yerel hızda yürütme

Maliyeti ne kadardır

  • Yerel bir çöküş tüm JVM'yi etkileyebilir.
  • Çöp toplayıcı desteği olmadan manuel bellek yönetimi.
  • Bakımını ve dağıtımını yapmak için platforma özel derlemeler.
  • Sık kullanılan döngülerde sınırları aşan ek yük

JNI ve Yabancı Fonksiyon ve Bellek API'si

JNI orijinal mekanizmadır, ancak artık tek seçenek değil. Yeni Java sürümleri, daha az ek kodla ve daha sıkı güvenlik garantileriyle yerel kodu çağırmak üzere tasarlanmış Yabancı Fonksiyon ve Bellek (FFM) API'sini içerir. JNI, her yerde olduğu ve kapsamlı bir şekilde anlaşıldığı için mevcut araç zincirlerinde hâlâ baskın durumdadır.

JNIFFM API
YaşOrijinal, Java'nın başlarında beri mevcutModern, son sürümlerde eklendi
Ek KodÜretilen başlıklar, adları değiştirilmiş C fonksiyonlarıJava'da tanımlanan yöntem tanıtıcıları, ara C kodu yok
Bellek GüvenliğiManuel; hatalar JVM'yi bozabilirDaha güçlü kontrollerle sınırlı segmentler
BenimsenmeMevcut kütüphanelerde yaygınArtan, yeni kod tabanlarında

Sıkça Sorulan Sorular

Terminus'u yakala

Built by people who actually read the JVM internals.