Kompliowanie plików dla JNI

JNI (Java Native Interface) umożliwia wywoływanie procedur znajdujących się w zewnętrznych bibliotekach (dll, so) i napisanych w innych językach programowania (C, C++).
Aby wykonać metodę znajdującą się w zew. bibliotece musi ona być zadeklarowana jako natywna w danej klasie np.:
private native void metoda();
Funkcję taką wywołujemy tak samo jak zwykłą metodę javową.
Dodatkowo należy załadować bibliotekę (tu przykład dla MyLibrary.dll):
static {
System.loadLibrary("MyLibrary");
//lub
//System.load("sieżka/do/pliku/MyLibrary.dll");
}

Teraz kilka słów o tym jak skompilować taką bibliotekę. Można użyć oczywiście do tego celu kompilatora gcc. Ponieważ przeważnie pracuję na systemie Windows zainstalowałem Cygwin. Pakiet ten zawiera pre-definiowane środowisko linuxowe (shell, programy) dla systemów Win32. Przy instalacji należy pamiętać aby zaznaczyć odpowiednie pakiety i biblioteki używane do kompliacji (np. gcc) oraz dodać katalogi cygwin i cygwin\bin (cygwin - katalog instalacyjny) do zmiennej systemowej PATH. Jeżeli wszystko działa możemy przystąpić do generowania odpowiednich plików. Najpierw generujemy plik nagłówkowy (.h) na podstawie naszej klasy (skompilowanej):

javah -jni -d pakiet.Klasa

Operacja stworzy w odpowiednie pliki .h, którego zawartość będzie podobna do:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class pakiet_Klasa */
#ifndef _Included_pakiet_Klasa
#define _Included_pakiet_Klasa
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: pakiet_Klasa
* Method: metoda
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_pakiet_Klasa_metoda
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif

Na podstawie tego pliku musimy napisać implementację (.c).
aby skompilować (i zlinkować) dla gcc pod Cygwin-em piszemy:
gcc-3 -mno-cygwin -D__int64="long long" -I
$jdk\include -I$jdk\include\win32 -Wl,--kill-at -shared -o MyLibrary.dll nazwa_pliku.c
gdzie $jdk to ścieżka do JDK.
Pamiętajmy, że aby biblioteka została załadowana musi znajdować się na ścieżce bibliotek javy (java.library.path). Domyślnie jest to np. c:\windows\system32. Aktualną wartość tego parametru możemy wyświetlić przy pomocy:
System.out.println(System.getProperty("java.library.path"));