000
26.08.2003, 16:28 Uhr
0xdeadbeef
Gott (Operator)
|
Moin,
Ich hab ein kleines Problem mit dem Java Native Interface. Folgendes: Ich muss eine Funktion in einer C-Bibliothek aus einer Java-Klasse ansprechen, die in einem Package, also auch in einem Unterverzeichnis liegt. Schema:
Code: |
$ tree . |-- Main.java |-- Main.class '-- beef '-- dead |-- Caller.java |-- Caller.class |-- Caller.h |-- Caller.c |-- libcaller.so |-- called.h '-- libcalled.so
|
libcalled ist die C-Bibliothek, die die eigentlichen Funktionen enthält. libcaller ist eine Interface-Bibliothek, die im wesentlichen dieselben Funktionen mir auf Java umgemünzten Datentypen bereitstellt, Caller ist eine Java-Klasse, die auf libcaller zugreift und die von libcaller exportierten Funktionen als statische Funktionen bereitstellt, die dann von Main aufgerufen werden können. Nehmen wir an, libcalled enthält eine Funktion double foo(double); Im Code sieht das etwa so aus: beef/dead/Caller.java
C++: |
package beef.dead;
public class Caller { public static native double foo(double);
static { System.loadLibrary("caller"); //wird von System zu libcaller.so erweitert, unter Windows caller.dll } }
|
Main.java
C++: |
import beef.dead.Caller;
class Main { public static void main(String[] args) { System.out.println(Caller.foo(2.0)); } }
|
Caller.h
C++: |
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Caller */
#ifndef _Included_Caller #define _Included_Caller #ifdef __cplusplus extern "C" { #endif /* * Class: Caller * Method: foo * Signature: (D)D */ JNIEXPORT jdouble JNICALL Java_Caller_foo (JNIEnv *, jclass, jdouble);
#ifdef __cplusplus } #endif #endif
|
Caller.c
C++: |
#include <jni.h> #include "Caller.h" #include "called.h"
JNIEXPORT jdouble JNICALL Java_Caller_foo(JNIEnv *env, jclass cls, jdouble d) { return foo(d); /* Aus libcalled */ }
|
Wenn ich jetzt java Main durchlaufen lasse, kriege ich folgende Fehlermeldung:
Code: |
Exception in thread "main" java.lang.UnsatisfiedLinkError: foo at beef.dead.Caller.foo(Native Method) at Main.main(Main.java:5)
|
Wenn ich die Dateien alle in ein Verzeichnis packe und das "package beef.dead" aus der Caller.java rausnehme, läuft es. Woran kann das liegen? -- Einfachheit ist Voraussetzung für Zuverlässigkeit. -- Edsger Wybe Dijkstra |