JNI UnsatisfiedLinkError ... undefined symbol: __cxa_pure_virtual

tdc

Bekanntes Mitglied
Hi,
ich habe (leider) wieder ein Problem bezüglich JNI. Ich möchte ein größeres C++-Programm (Bullet Physics Engine, ja, es gibt JBullet, ich bräuchte aber die aktuellste, vollständige Version) über JNI ausführen. Deshalb habe ich es als *.so kompiliert und eine weitere C-Klasse geschrieben, die die Engine verwendet (in diesem Fall ein Hello-World-Programm ausführt). Diese zweite *.so-Datei möchte ich nun über JNI aufrufen.
Zurzeit erhalte ich allerdings eine Fehlermeldung. (siehe unten)

Zuvor hatte ich das Problem, dass ich für gcc erst noch den Ort für die Header, zusätzlich zu den *.so-Dateien angeben musste (-I/home/pfad/bullet-2.80-rev2531/src). Muss ich für JNI ebenfalls zusätzliche Parameter für die Header angeben?
Eigentlich dürfte sich, im Gegensatz zu meinen vorigen Versuchen mit JNI, ja nicht viel verändert haben. Im Quellcode verweise ich jetzt nur zusätzlich auf einen Header, die Compilierung der C++-Klasse funktioniert durch die zusätzliche Pfadangabe aber reibungslos.
Warum erhalte ich dann später beim Ausführen durch Java eine Fehlermeldung?
Diesmal sollten auch die Bezeichnungen der *.so-Dateien stimmen.

C++-Klasse
Code:
#include <jni.h>
#include <iostream>
#include <btBulletDynamicsCommon.h>
 
JNIEXPORT void JNICALL Java_jni_callnative(JNIEnv *env,
                                                  jobject obj)
{

        return ;
}

Compile-Script:
Code:
javac jni.java
javah -jni jni
gcc -fPIC -shared -I/home/pfad/bullet-2.80-rev2531/src -I/usr/local/java/include -I/usr/local/java/include/genunix hello.cpp -o libhello.so -LBulletCollision -LBulletDynamics -LBulletMultiThreaded -LBulletSoftBody -LLinearMath -LMiniCL
export LD_LIBRARY_PATH="/home/pfad/JNIBulletHello"
java jni

Fehlermeldung:
Code:
Exception in thread "main" java.lang.UnsatisfiedLinkError: /home/pfad/JNIBulletHello/libhello.so: /home/pfad/JNIBulletHello/libhello.so: undefined symbol: __cxa_pure_virtual
	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
	at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1939)
	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1864)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1854)
	at java.lang.Runtime.loadLibrary0(Runtime.java:845)
	at java.lang.System.loadLibrary(System.java:1084)
	at jni.<clinit>(jni.java:9)
 

tdc

Bekanntes Mitglied
Okay. Wenn ich ein (Hello-World-)Beispielprogramm als C-Programm kompiliere, funktioniert es. Als C++-Programm funktioniert es nicht und ich bekomme unterschiedliche UnsatisfiedLinkErrors. Warum?
 

Marco13

Top Contributor
Der UnsatisfieldLinkError ist eben so omnipräsent (er fliegt ja immer wenn irgendwas schiefgeht) dass man wohl spezifischer werden muss. Eine websuche nach
unsatisfiedlinkerror undefined symbol: __cxa_pure_virtual
liefert (diese Thread hier als erstes Ergebnis, aber auch noch) ein paar Ergebnisse von anderen Seiten, aber ich habe nocht nicht näher geschaut... :oops:
 

tdc

Bekanntes Mitglied
Okay, ich habe scheinbar mehrere Fehler gemacht. Ich versuche zurzeit nur ein einfaches C++-Hello-World-Programm mit JNI auszuführen (mit C funktioniert es ja bereits).
Mit g++ bekomme ich jetzt nur wieder:
Code:
Exception in thread "main" java.lang.UnsatisfiedLinkError: jni.callnative()V
	at jni.callnative(Native Method)
	at jni.main(jni.java:5)
Programm:
Code:
#include <jni.h>
#include <stdio.h>
#include <iostream>
using namespace std;

JNIEXPORT void JNICALL Java_jni_callnative(JNIEnv *env,
                                                  jobject obj)
{
   cout << "Hello World!";
   return;
}
Compile-Script:
Code:
javac jni.java
javah -jni jni
g++ -fPIC -shared -I/usr/local/java/include -I/usr/local/java/include/genunix hello.cpp -o libhello.so
export LD_LIBRARY_PATH="/home/oliver/Arbeitsfläche/javaTest/JNITestpp"
java jni
Und die Java-Klasse:
Java:
class jni {
  private native void callnative();

  public static void main(String[] args) {
    new jni().callnative();
  }

  static {
    System.loadLibrary("hello");
  }
}

Sobald ich mit JNI das C++-Programm anstatt das C Hello World Programm verwenden möchte, bekomme ich den Error. Ändern tue ich dabei nur den C-Quellcode (C++ statt C) und ich verwende g++ anstatt gcc.
Muss ich noch mehr verändern? Sind die Parameter ok?
 

Marco13

Top Contributor
Ich würde ja wieder auf das kill-at verweisen (wie im letzten Thread) aber vermutlich habe ich mit dem GCC einfach zu wenig praktische Erfahrung, um sinnvolleres beitragen zu können...:oops:
 

tdc

Bekanntes Mitglied
Ich würde ja wieder auf das kill-at verweisen (wie im letzten Thread) aber vermutlich habe ich mit dem GCC einfach zu wenig praktische Erfahrung, um sinnvolleres beitragen zu können...:oops:

Und wie schon im letzten Thread kann ich nur wieder sagen, dass mein gcc/g++ das nicht zu kenn en scheint. ;) (bzw. dass ich es bei mir nicht funktioniert...)

Code:
g++ -Wl,--kill-at -fPIC -shared -I/usr/local/java/include -I/usr/local/java/include/genunix hello.cpp -o libhello.so
statt
Code:
g++ -fPIC -shared -I/usr/local/java/include -I/usr/local/java/include/genunix hello.cpp -o libhello.so
ergibt
Code:
/usr/bin/ld: unrecognized option '--kill-at'
/usr/bin/ld: use the --help option for usage information
collect2: ld gab 1 als Ende-Status zurück
kann natürlich auch sein, dass ich irgendetwas total falsch mache... :oops:
 

jamesv

Bekanntes Mitglied
Hallo,
hier ist zu finden, dass du erst ein .o File erstellen musst und dann die --kill-at anweisung verwenden.

jni - MinGW's compiler option Wl,--kill-at does not work - Stack Overflow


Ich hoffe, dass dir das hilft.

Kommando:

g++ -I"C:\Program Files\Java\jdk1.6.0_13\include" -I"C:\Program Files\Java\jdk1.6.0_13\include\win32" -O0 -Wall -c -oMain.o ..\Main.cpp


zweites Kommando, dass auf das O-File geht:

g++ -Wl,--kill-at -shared -olibJniCTest.dll Main.o


Müsstest halt noch die Pfade austauschen :)
 

tdc

Bekanntes Mitglied
Nein, auch das hilft nicht, mein Compiler kennt es einfach nicht.

Nach einigem Suchen scheint es wohl einfach unter Linux nicht nötig zu sein:
Linker Flag hinzufügen : Trage unter "Project -> properties -> C/C++ Build -> Settings -> MinGW C Linker -> Miscellaneous -> Linker flags" den Wert ein:
"-Wl,--kill-at"
(Das ist nötig, weil sonst die DLL beim Kompillieren mit @-Zeichen angereichert wird, die Java nicht versteht. Unter Linux braucht es dieses Flag nicht)
Quelle: JNI Tutorial
(Außerdem kennt der Compiler unter Linux es scheinbar einfach nicht)

Was könnte ich denn sonst noch falsch gemacht haben?
 

tdc

Bekanntes Mitglied
Oooookay, es scheint ein:
Code:
extern "C"
gefehlt zu haben.
So funktioniert es jetzt:
Code:
#include <jni.h>
#include <stdio.h>
#include <iostream>
using namespace std;

extern "C"
JNIEXPORT void JNICALL Java_jni_callnative(JNIEnv *env,
                                                  jobject obj)
{
   cout << "Hello World!" << endl;
   return;
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
C OpenCV: UnsatisfiedLinkError Allgemeine Java-Themen 5
T Eclipse Dll einbinden java.lang.UnsatisfiedLinkError nur in Eclipse nicht via javac Allgemeine Java-Themen 1
T JNI - UnsatisfiedLinkError Allgemeine Java-Themen 9
B JNI - java.lang.UnsatisfiedLinkError Allgemeine Java-Themen 21
Hindi93 Fehlermeldung UnsatisfiedLinkError Allgemeine Java-Themen 8
eQuest JNI UnsatisfiedLinkError Allgemeine Java-Themen 5
N Exception in thread "main" java.lang.UnsatisfiedLinkError: no lwjgl in java.library.p Allgemeine Java-Themen 4
heart_disease Probleme mit JNI: UnsatisfiedLinkError Allgemeine Java-Themen 6
L UnsatisfiedLinkError mal anders Allgemeine Java-Themen 4
I java.lang.UnsatisfiedLinkError: Allgemeine Java-Themen 8
J JNI: UNsatisfiedLinkError Allgemeine Java-Themen 3
D java.lang.UnsatisfiedLinkError Allgemeine Java-Themen 5
S java.lang.UnsatisfiedLinkError mit JNI Allgemeine Java-Themen 6
H JNI: loadLibrary liefert UnsatisfiedLinkError Allgemeine Java-Themen 2
T unsatisfiedlinkerror -> Diese Anwendung konnte nicht gest Allgemeine Java-Themen 2
K UnsatisfiedLinkError bei -> VTKInit Allgemeine Java-Themen 2
M JNI: nach verschieben in package UnsatisfiedLinkError Allgemeine Java-Themen 3
D JNI: UnsatisfiedLinkError Allgemeine Java-Themen 3
R JNI unsatisfiedLinkError Allgemeine Java-Themen 5
Thallius JSONArray - the method length() is undefined for JSONArray Allgemeine Java-Themen 4
M Interpreter-Fehler JNI undefined symbol Allgemeine Java-Themen 1
P sql.Date -> the constructor Date() is undefined! Allgemeine Java-Themen 3
Mick P. F. Wie kriege ich die Fehlermeldung "java: symbol lookup error: ..." weg? Allgemeine Java-Themen 11
bueseb84 Java : Cannot find Symbol Allgemeine Java-Themen 7
C Compiler-Fehler Cannot find symbol bei Hat-Beziehungen Allgemeine Java-Themen 5
C Symbol für Gaußsche Summenformel in Kommentarzeile darstellen Allgemeine Java-Themen 3
D Symbol in Word-Dokument einfügen Allgemeine Java-Themen 1
127.0.0.1 Methodenaufruf -cannot find symbol- Allgemeine Java-Themen 14
Tobse Cannot find symbol : construktor --- Deklariert! Allgemeine Java-Themen 9
D 'InputStreamReader' & 'BufferedReader' führen zu "cannot find symbol"-Fehler Allgemeine Java-Themen 3
B cannot find Symbol Allgemeine Java-Themen 2
I Reguläre Ausdrücke und das "~" Symbol Allgemeine Java-Themen 2
H Symbol je Dateiendung? Allgemeine Java-Themen 6
G Kompiler Fehler: cannot resolve symbol: class Allgemeine Java-Themen 4
7 Cannot resolve Symbol keyPressed Allgemeine Java-Themen 3
B Symbol in Systray Allgemeine Java-Themen 9
G Fehlermeldung "cannot resolve symbol" Allgemeine Java-Themen 7
V Cannot resolve symbol Allgemeine Java-Themen 7

Ähnliche Java Themen

Neue Themen


Oben