Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem mit JNI und shared libs

0 views
Skip to first unread message

Gerrit Kuehn

unread,
Aug 18, 2003, 11:27:29 AM8/18/03
to
Hallo Leute,

ich habe gerade glaube ich irgendwie ein Brett vor'm Kopf; vielleicht kann
mir hier jemand sagen, wo's genau klemmt.
Also, meine Situation ist folgende: Meine Plattform ist Gentoo-Linux mit
einem gcc 3.2.3 sowie einem IBM-JDK 1.4.0. Ich habe den Code für ein
JavaNativeInterface mit dem Namen JniGPIB.cpp. Daraus kompiliere ich
mittels "gcc -shared -o libJniGPIB.so -lggpibfx JniGPIB.cpp" eine shared
lib namens libJniGPIB.so. Das Interface ist im Prinzip nur ein Wrapper für
die Bibliothek ggpibfx, in der die eigentlichen Funktionen 'drinstehen.
Diese lib hatte ich vorher bereits mittels "gcc -shared -o libggpibfx.so
ggpibfx.c" erzeugt. Beide libs habe ich in den entsprechenden lib-Pfad
kopiert und danach "ldconfig" aufgerufen.
gcc scheint auch alles korrekt gelinkt zu haben:

mess@hquer gpib $ ldd libggpibfx.so
libc.so.6 => /lib/libc.so.6 (0x40011000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)

mess@hquer gpib $ ldd libJniGPIB.so
libggpibfx.so => /usr/lib/libggpibfx.so (0x40010000)
libc.so.6 => /lib/libc.so.6 (0x40014000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)

Wenn ich jetzt aber ein Testprogramm aufrufe, das die Bibliotheken
benutzen soll, meckert das über folgendes:

mess@hquer pmppackages $ java prototype/programms/GetWfmTDS210
Exception in thread "main" java.lang.UnsatisfiedLinkError:
/usr/lib/libJniGPIB.so: /usr/lib/libJniGPIB.so: undefined symbol:
_Z6IeInittttt
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1951)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1837)
at java.lang.Runtime.loadLibrary0(Runtime.java:805)
at java.lang.System.loadLibrary(System.java:883)
at at
prototype.gpib.GPIB.<clinit>(GPIB.java:111).null(Unknown Source)
at prototype.programms.GetWfmTDS210.main(GetWfmTDS210.java:17)


Mit Blick in meine Bibliothek finde ich dann u.a. folgendes:

mess@hquer gpib $ nm libJniGPIB.so
00001a46 T Java_prototype_gpib_GPIB_gpibcleanup
000017cc T Java_prototype_gpib_GPIB_gpibclear
000012a6 T Java_prototype_gpib_GPIB_gpibdevinit
000011e4 T Java_prototype_gpib_GPIB_gpibinit
0000190c T Java_prototype_gpib_GPIB_gpibllo
0000186c T Java_prototype_gpib_GPIB_gpiblocal
00001460 T Java_prototype_gpib_GPIB_gpibread
00001668 T Java_prototype_gpib_GPIB_gpibreadbytes
00001586 T Java_prototype_gpib_GPIB_gpibreadfile
000019a6 T Java_prototype_gpib_GPIB_gpibtrigger
00001368 T Java_prototype_gpib_GPIB_gpibwrite
000022b0 A _DYNAMIC
00002394 A _GLOBAL_OFFSET_TABLE_
w _Jv_RegisterClasses
U _Z5IeLLOv
U _Z5IeSettttt
U _Z5IeUNLv
U _Z5IeUNTv
U _Z6IeInittttt
U _Z7IeCleart
U _Z7IeEnterttPhPt
U _Z7IeLocalt
U _Z8IeOutputttPhPt
U _Z9IeEntFilettPh
U _Z9IeTriggert

Die Java_*-Sachen sind die von mir implementierten Funktionen. Die mit "U"
gekennzeichneten Symbole kommen im Source gar nicht vor, die hat sich der
Compiler wohl beim Übersetzen erzeugt.
Meine Frage ist nun (und die hat mir auch exzessives Googlen und das
Befragen diverser Kollegen nicht beantworten können :-): Wieso werden
diese Symbole nicht gefunden, und was kann ich dagegen tun?


cu
Gerrit

Jürgen Ockert

unread,
Aug 18, 2003, 12:00:23 PM8/18/03
to
Hallo Gerrit,

JNI kann kein C++ sondern nur C (zumindest nicht so einfach).
Probiers mal mit umbenennen deiner JniGPIB.cpp in JniGPIB.c dann sollten
die Symbole stimmen.

Gruß

Jürgen

Gerrit Kuehn

unread,
Aug 18, 2003, 12:13:19 PM8/18/03
to
Jürgen Ockert wrote:

> JNI kann kein C++ sondern nur C (zumindest nicht so einfach).

?
Ich hab' schon mehrere Interfaces so geschrieben, exakt dieses läuft unter
Windows mit msvc auch einwandfrei. Bis jetzt hat nur gcc diese Zicken gemacht.

> Probiers mal mit umbenennen deiner JniGPIB.cpp in JniGPIB.c dann sollten
> die Symbole stimmen.

Umbenennen reicht da nicht, das kompiliert dann nicht mehr durch:

mess@hquer gpib $ gcc -shared -o libJniGPIB.so -lggpibfx JniGPIB.c
JniGPIB.c: In function `Java_prototype_gpib_GPIB_gpibinit':
JniGPIB.c:14: parameter name omitted
JniGPIB.c:20: request for member `FindClass' in something not a structure
or union
JniGPIB.c:30: request for member `ThrowNew' in something not a structure
or union

[...usw...]


Natürlich kann ich die Aufrufe jetzt entsprechend umbauen; aber javah hat
mir die Dinger doch extra so erzeugt, sogar unter Berücksichtigung von c++?!


cu
Gerrit

Holger Hoffstaette

unread,
Aug 18, 2003, 1:49:46 PM8/18/03
to
On Mon, 18 Aug 2003 17:27:29 +0200, Gerrit Kuehn wrote:

> [...]


> einem gcc 3.2.3 sowie einem IBM-JDK 1.4.0. Ich habe den Code für ein
> JavaNativeInterface mit dem Namen JniGPIB.cpp. Daraus kompiliere ich
> mittels "gcc -shared -o libJniGPIB.so -lggpibfx JniGPIB.cpp" eine shared

Versuch mal, das -lggpibfx ans Ende zu stellen.

Holger
--
A: Maybe because some people are too annoyed by top-posting.
Q: Why do I not get an answer to my question(s)?
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

Gerrit Kuehn

unread,
Aug 19, 2003, 2:12:30 AM8/19/03
to
Holger Hoffstaette wrote:

>>mittels "gcc -shared -o libJniGPIB.so -lggpibfx JniGPIB.cpp" eine shared

> Versuch mal, das -lggpibfx ans Ende zu stellen.

Bringt leider keine Veränderung.


cu
Gerrit

moovida

unread,
Aug 20, 2003, 7:05:05 PM8/20/03
to
Ich denke JNI kennt sowohl C als auch C++, nur ist die Syntax ein
wenig anderst.

> Umbenennen reicht da nicht, das kompiliert dann nicht mehr durch:
> mess@hquer gpib $ gcc -shared -o libJniGPIB.so -lggpibfx JniGPIB.c
> JniGPIB.c: In function `Java_prototype_gpib_GPIB_gpibinit':
> JniGPIB.c:14: parameter name omitted
> JniGPIB.c:20: request for member `FindClass' in something not a structure
> or union
> JniGPIB.c:30: request for member `ThrowNew' in something not a structure
> or union

Dies passiert (Hypotese), da man in C (*env)->FindClass(env,
signature) schreibt, waehrend es in C++ env->FindClass(signature) ist
(oder in etwa).
Wenn du umbenennst, dann interpretiert er es als C.


> mess@hquer pmppackages $ java prototype/programms/GetWfmTDS210
> Exception in thread "main" java.lang.UnsatisfiedLinkError:
> /usr/lib/libJniGPIB.so: /usr/lib/libJniGPIB.so: undefined symbol:
> _Z6IeInittttt
> at java.lang.ClassLoader$NativeLibrary.load(Native Method)
> at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1951)

Hast du probiert, die shared lib nur zu compilieren und dann

java -Djava.library.path=*.so_Pfad prototype/programms/GetWfmTDS210

aufzurufen?

Sind die Funktionsprototypen in den C-Sources gleich denen in den
Header-files?


Anderes faellt mir nicht ein.
Ciao Andrea

Gerrit Kuehn

unread,
Aug 21, 2003, 11:18:12 AM8/21/03
to
moovida wrote:

> Ich denke JNI kennt sowohl C als auch C++, nur ist die Syntax ein
> wenig anderst.

Der Meinung bin ich auch. Deswegen wundere ich mich ja auch, daß meine
c++-Version an dieser Stelle nicht funktioniert. Solche Probleme hatte ich
damit noch nie; irgendwie scheint der Linker den Ärger zu machen... den
Code habe ich ohnehin nur ,,geerbt'', so richtig blicke ich den eh noch nicht.

>>JniGPIB.c: In function `Java_prototype_gpib_GPIB_gpibinit':
>>JniGPIB.c:14: parameter name omitted
>>JniGPIB.c:20: request for member `FindClass' in something not a structure
>>or union
>>JniGPIB.c:30: request for member `ThrowNew' in something not a structure
>>or union

> Dies passiert (Hypotese), da man in C (*env)->FindClass(env,
> signature) schreibt, waehrend es in C++ env->FindClass(signature) ist
> (oder in etwa).

Ja, genau. Das habe ich mittlerweile auch mal umgesetzt.

> Wenn du umbenennst, dann interpretiert er es als C.

Habe ich mittlerweile gemacht, bis auf diese beiden Sachen:

buf = (char*)jEnv->GetStringUTFChars(jEnv, jcommand, 0);

return (jstring)jEnv->NewStringUTF((const char*)buf);

Ich weiß leider nicht, wie ich das mit den Typecasts korrekt in C
formulieren kann.
Auch die Fehler mit "parameter name omitted" sind komplett geblieben (für
jede Funktion/Methode einer); irgendwie scheint der Header da noch nicht
richtig zu sein.

>>mess@hquer pmppackages $ java prototype/programms/GetWfmTDS210
>>Exception in thread "main" java.lang.UnsatisfiedLinkError:
>>/usr/lib/libJniGPIB.so: /usr/lib/libJniGPIB.so: undefined symbol:
>>_Z6IeInittttt
>> at java.lang.ClassLoader$NativeLibrary.load(Native Method)
>> at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1951)

> Hast du probiert, die shared lib nur zu compilieren und dann
> java -Djava.library.path=*.so_Pfad prototype/programms/GetWfmTDS210
> aufzurufen?

Nein, ich habe die libs nach dem Compilieren nach /usr/lib kopiert und
ldconfig aufgerufen. Damit sollte Java sie eigentlich finden (tut es ja
auch - beschwert sich nur über die Symbole). Danach habe ich dann "java
prototype/programms/GetWfmTDS210 aufgerufen".

> Sind die Funktionsprototypen in den C-Sources gleich denen in den
> Header-files?

An welcher Stelle jetzt genau? Ich habe einen Header namens ggpibfx.h, der
zu ggpibfx.c gehört und einen (mit javah erzeugten), der zu JniGPIB.c(pp)
gehört. Der Header für ggpibfx paßt zu den Sourcen. Dieser Header wird
auch von JniGPIB includet, ebenso wie der von javah erzeugte Header. Die
Köpfe für JniGPIB habe ich direkt aus diesem Header kopiert. Sollte imho
eigentlich alles richtig sein, oder?!

> Anderes faellt mir nicht ein.

Danke, daß Du 'drüber nachgedacht hast. :)
Meine Kollegen hier, ich sich damit sonst eigentlich recht gut auskennen,
gucken auch seit ein paar Tagen schon ziemlich belämmert...


cu
Gerrit

0 new messages