**taşındım : yugruk.blogspot.com
Java ile java kodlarının yanında doğal dil (c,c++,pascal vs) kodlarınıda çalıştırabilirsiniz.Aslında genel anlamda Java doğal dil fonksiyonlarının sıkı bir düzende kurulmuş halidir.
Javaya doğal dil entegre etmek istersek en uygun dil C veya C++ tır.Ben C üzerinden bu entegre işlemi nasıl anlatmaya çalışacağım.
Java ile doğal kodu entegre etme işleminde 2 adet kod dosyası olacak birini kod java kodu diğeri de doğal dil kodu.Java ile doğal kod fonksiyonları doğal kodun derlenmesi sonucunda ortaya çıkan paylaşılabilir (shared) obje dosyasının java kodu tarafından,Java (aslında JVM) fonksiyon tablosuna yüklenmesini tetikleyerek gerçekleşir,yani obje dosyasının yüklenmesini tamamen siz kontrol ediyorsunuz.Obje dosyası içeri alındıktan sonra java kodlarında bu doğal kodları kullanabiliriz.
Örnek java kodu şu olsun :
public class HelloTest{
public native void hello();
static{
System.loadLibrary(”hello”);
}
}
bu java kodu ile yapmak istediğim şu bir tane doğal dilde yazılmış hello kodunu javadan çağırmak.bu yüzden hello fonksiyonun native olarak tanımlıyorum.System.loadLibrary(”hello”); kodu ile doğal dilde yazılmış fonksiyonumuzu taşıyan obje dosyasını Java içerisine alıyoruz.
Java kodunu yazdıktan sonra bu kodu derlemeliyiz çünkü C kodumuzda kullanmak üzere bir header dosyasına ihtiyacımız var ve bunu javah adlı program ile yapıyoruz.
javac HelloTest ile derledikten sonra javah -jni HelloTest dediğimiz zaman ortaya HelloTest.h adlı bir header dosyası çıkar.Bu dosyada java tarafından çağrılacak fonksiyonun C deki adını gösteren bir fonksiyon deklarasyonu var.Yani bizim yazmamız gereken C fonksiyonunun tanımı var.
Java kodunu derleyip javah -jni dedikten sonra ortaya çıkan dosya şu :
/* DO NOT EDIT THIS FILE – it is machine generated */
#include
/* Header for class HelloTest */
#ifndef _Included_HelloTest
#define _Included_HelloTest
#ifdef __cplusplus
extern “C” {
#endif
/*
* Class: HelloTest
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloTest_hello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Biz bu headeri C kodumuza include edip bu headerdaki fonksiyonu yazacağız.
#include
#include “HelloTest.h”
JNIEXPORT void JNICALL Java_HelloTest_hello(JNIEnv *env, jobject obj)
{
printf(”Hello from C\n”);
}
bu C kodunu hello.c olarak kaydeddikten sonra bir C derleyicisi ile derleriz,yalnız burada dikkat edilmesi gerekn bir nokta var,bu aşamada sadece derleme olmak zorunda yani varsayılan derlemeyi yaparsak derleyici bize executable bir dosya oluşturur fakat C kodunun main metodu olmadığı için bu dosyayı çalıştıramayız,zaten istediğimiz paylaşıalbilir dosya çalıştırılabilir dosya değil.
derlemek için Linuxta GCC kullanarak şu komutları veririz,Windows için biraz araştırma yapmanız gerekecek.
gcc -c hello.c -I/sisteminizdeki_jdk_ninyolu/include/ -I/sisteminizdeki_jdk_ninyolu/include/linux
bu komut ile .o uzantılı linklenmemiş yani printf fonksiyonun kodunu içermeyen bir obje dosyası oluşur.Bunu paylaşılabilir ve linklenmiş dosya haline getirmeliyiz ki kullanılabilir bir dosya olsun.
gcc -shared -fPIC hello.o -o hello.so
Bu komutta -shared parametresi dosyayı paylaşıalbilir yapıyor -fPIC ile obje dosyamızdaki fonksiyonumuz java içerisine alındığı zaman herhangi bir adrese taşınabiliyor.
Her şey tamam.Elimizde hello.so,HelloTest.class olmak üzere işe yarar 2 tane dosya var.Yeni bir java kodu ile bunları kullanılaiblir hale getiririz
public class test{
public static void main(String args[])
{
new HelloTest().hello();
}
}
bu kodu derleyip java test diyerek konsolda çalıştırdığımız zaman bize Hello From C mesajını verecektir.Eğer o mesajı yazarsa herşey düzgün şekilde işliyor demektir.
Bu işlemleri yaparken çıkabilecek hatalar genelde derleme aşamasında -I parametresinin unutulması,Java tarafından .so dosyasının yüklenememesi gibi kolayca çözülebilecek hatalardır.
Java tarafından .so dosyanız yüklenemez ise
static{
System.loadLibrary(”hello”);
}
kodu yerine
static{
System.load(”hello.so_nun_tam_yolu”);
}
şeklindeki kodu yazın burada load fonksiyonu parametre olarak hello.so dosyamızı gösteren tam yolu alır.
Kategorisi: GCC, JNI, Java, Linux, Programlama
