Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » Java » Jni und Verzeichnisstruktur

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ]
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
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
26.08.2003, 18:46 Uhr
0xdeadbeef
Gott
(Operator)


Manchmal seh ich aber auch echt den Wald vor Bäumen nicht. Die Funktion in C muss natürlich beef_dead_Caller_foo heißen, um Doppeldeutigkeiten zu vermeiden. ARGH!

Na gut, inzwischen kann ich native Funktionen aufrufen. Jetzt hab ich das Problem, dass er mir ständig abschmiert, und ich keine Ahnung hab, warum. Ich könnte

Wie auch immer.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
27.08.2003, 09:05 Uhr
virtual
Sexiest Bit alive
(Operator)


Ich denke, man müsste wissen, was bei foo(d); genau passiert.

Ach und nochwas: ich habe die Erfahrung gemacht, daß man beim JNI peinlich genau drauf achten muß, daß man den ExceptionStack schön sauber hält: sobald was passiert, was eine Exception auslösen könnte, diese auslesen und vorallem löschen, sonst tut sich da nix mehr.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
27.08.2003, 09:14 Uhr
0xdeadbeef
Gott
(Operator)


Hm. Klingt logisch, aber wie fange ich in C Exceptions?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
27.08.2003, 09:29 Uhr
virtual
Sexiest Bit alive
(Operator)


Im JNI Code zB:

C++:
...
EtwasWasEineExceptionAuslösenKönnte();
jthrowable ex = env->ExceptionOccurred(); // Hole Exception Object
if (ex)
{
    env->ExceptionDescribe(); // Print Exception stack
    // Alternativ kannst Du auch direkt was mit ex machen
    env->ExceptionClear(); // Exception stack sauber halten
}
...


Näheres dazu:http://java.sun.com/j2se/1.3/docs/guide/jni/spec/functions.doc.html#5234
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
27.08.2003, 10:00 Uhr
0xdeadbeef
Gott
(Operator)


Hm. OK, ich hab den Code jetzt auf C umgemünzt:

C++:
  jthrowable ex = (*env)->ExceptionOccurred(env);
  if(ex) {
    (*env)->ExceptionDescribe(env);
    (*env)->ExceptionClear(env);
    return 0.0L;
  }


Bringt aber auch nichts. Ich krieg diesen Fehler:

Code:
An unexpected exception has been detected in native code outside the VM.
Unexpected Signal : 11 occurred at PC=0x400DEE33
Function=__libc_free+0x3F
Library=/lib/libc.so.6

Current Java thread:
        at beef.dead.Caller.foo(Native Method)
        at Main.main(Main.java:5)


Danach ne Liste der geladenen Bibliotheken (vieeele), einen Heapdump und eine Mitteilung, man habe das alles auch in eine Logfile geschrieben. Wenn ich das ganze von C aus aufrufe (ohne Exception-Handler), läuft es anstandslos, die Bibliothek ist also nicht buggy. Hmm...
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 27.08.2003 um 10:01 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
27.08.2003, 10:24 Uhr
virtual
Sexiest Bit alive
(Operator)


Die Meldung legt nahe, daß Du da irgendwas mit free machst.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
27.08.2003, 10:29 Uhr
0xdeadbeef
Gott
(Operator)


Scheint so. Auf der anderen Seite macht das Ding keine Probleme, wenn ichs aus C aufrufe, was nahelegt, dass der Fehler an der Anbindung zur JVM liegt. Verdammt, das wird richtig schmerzhaft zu debuggen.

Naja, danke für deine Hilfe. Wenn ich raushab, woran es lag, meld ich mich wieder...
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
27.08.2003, 10:42 Uhr
virtual
Sexiest Bit alive
(Operator)


Mal ne blöde frage: Ist dein C reentrant compiliert? - Ich könnte mir auch vorstellen, daß - wiel Java ja ganz gerne multithreaded arbeitet - du eine nonreentrant Version von free gelinkt hast.
Auch wenn das nicht Dein Problem beheben sollte, ist es jedenfalls eine Überlegung wert, das zu machen...
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)

Dieser Post wurde am 27.08.2003 um 10:44 Uhr von virtual editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
27.08.2003, 11:29 Uhr
0xdeadbeef
Gott
(Operator)


Daaaa muss ich mal denjenigen fragen, der diese Library geschrieben hat. Mal kucken.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ]     [ Java ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: