22.2Eine C-Funktion in ein Java-Programm einbinden
Wir wollen in einem kurzen Überblick sehen, wie die Vorgehensweise prinzipiell ist. Dazu werfen wir einen Blick auf die Implementierung einer einfachen Klasse, die lediglich die Länge der Zeichenkette berechnet.
22.2.1Den Java-Code schreiben
Zunächst benötigen wir eine Klasse mit einer nativen Java-Methode. Wir haben gesehen, dass dafür der Modifizierer native nötig ist. Die Methode besitzt – wie eine abstrakte Methode – keine Implementierung:
Die statische Methode soll in eine Klasse mit einem statischen Initialisierungsblock eingebettet werden, der die dynamische Bibliothek lädt:
Listing 22.1com/tutego/jni/StrLen.java
public class StrLen {
static {
System.loadLibrary( "strlen" );
}
public static native int strlen( String s );
}
Die statische Methode System.loadLibrary(String) delegiert an Runtime.getRuntime().loadLibrary(String), die wir auch hätten nutzen können. Der Name der Bibliothek, "strlen", hat nichts mit dem Namen der Methode zu tun.
[»]Hinweis
Eine dynamische Bibliothek ist an einen Klassenlader gebunden und wird auch entfernt, wenn die Garbage-Collection den Klassenlader entfernt. Dennoch kann dieselbe aktive Bibliothek nur einmal von der JVM geladen werden. Ein zweiter Versuch wird mit einem UnsatisfiedLinkError bestraft.
Eine Beispielklasse soll lediglich unsere statische Methode aufrufen:
Listing 22.2com/tutego/jni/StrLenDemo.java
public class StrLenDemo {
public static void main( String[] args ) {
System.out.println( StrLen.strlen("2003 UB313") );
}
}
Suchort der dynamischen Bibliothek
Um bei der Aufforderung mit loadLibrary(String) die dynamische Bibliothek zu finden, wertet die Laufzeitumgebung die Umgebungsvariable LD_LIBRARY_PATH aus. Diese muss unter Umständen noch gesetzt werden. Befinden wir uns im selben Verzeichnis, ist das nicht nötig.
Welche Pfade die Laufzeitumgebung durchsucht, zeigt die folgende einfache Zeile:
Eine Alternative zu System.loadLibrary(String) ist die statische Methode System.load(String). Im Gegensatz zu loadLibrary(String) erwartet load(String) einen absoluten Pfad zur Bibliothek.