[Java] JNI vindt method niet in dll

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • flux_w42
  • Registratie: November 2006
  • Laatst online: 07-09-2024

flux_w42

jah, nu is het helemaal kapot

Topicstarter
Ik zou graag eens iets doen met JNI, gewoon als test om te zien wat je er allemaal mee kan doen. Educatief prutsen zeg maar :P Ik ben nu al enkele uren bezig aan het proberen iets werkend te krijgen, maar loop met m'n hoofd keihard tegen de (spreekwoordelijke) muur :'(

Wat ik ook probeer, ik blijf de volgende exceptie krijgen:

Exception in thread "main" java.lang.UnsatisfiedLinkError: info.fluxprojects.JniTest.testMethod()V
	at info.fluxprojects.JniTest.testMethod(Native Method)
	at info.fluxprojects.JniTest.main(JniTest.java:19)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)


Om eens een voorbeeldje te geven, een basic java class met één simpele method:


Java: JniTest.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package info.fluxprojects;

public class JniTest {

    public native void testMethod();

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

    public static void main(String[] args) {
        new JniTest().testMethod();
    }

}


Ik compile m'n class (jdk 1.6.0_21) en run dan javah zonder problemen om m'n header file te genereren:

javah -jni -o JniTest.h info.fluxprojects.JniTest


Met de volgende file als resultaat, so far so good ... :
C: JniTest.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class info_fluxprojects_JniTest */

#ifndef _Included_info_fluxprojects_JniTest
#define _Included_info_fluxprojects_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     info_fluxprojects_JniTest
 * Method:    testMethod
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_info_fluxprojects_JniTest_testMethod
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif


Mijn tijdelijke implementatie ziet er zo uit:
C: JniTest.c
1
2
3
4
5
#include "JniTest.h"

JNIEXPORT void JNICALL Java_info_fluxprojects_JniTest_testMethod(JNIEnv * e, jobject o){
    return;
}


Dat compiled perfect naar een dll (jnitest.dll), maar als ik nu de method call zoals in m'n java class staat krijg ik bovenstaande exceptie. De dll staat zeker in z'n classpath, dat is het probleem niet. Mocht dit niet zo zijn zou ik een andere exceptie krijgen (java.lang.UnsatisfiedLinkError: no jnitest in java.library.path).

Na heel wat googlen ben ik op deze site uitgekomen waar iemand dezelfde exceptie krijgt als ik.

Aangezien ik zo goed als geen ervaring heb met C, vermoedde ik eerst dat m'n dll niet in orde was (method niet geëxporteerd?) Dus heb ik via een tooltje (DLL Export Viewer) m'n method bekeken. Volgens mij ziet dat er goed uit ...

Afbeeldingslocatie: http://home.scarlet.be/~jm375900/jnitest/jni_exported_methods.png

Ik heb ook geen rare of unresolved dependencies:

Afbeeldingslocatie: http://home.scarlet.be/~jm375900/jnitest/jni_dependency_walker.png

Momenteel heb ik geen idee meer. Iemand meer ervaring met JNI die me op weg kan helpen? Dit is de dll die ik uit bovenstaande code gegenereerd heb.

Acties:
  • 0 Henk 'm!

  • MikeN
  • Registratie: April 2001
  • Laatst online: 09-10 15:28
Hoe compile je de DLL? Deze link geeft aan dat bepaalde compiler opties nog wel eens een verschil maken: http://witte-consulting.c...find-dependent-libraries/

Zelf geen ervaring met JNI, en zit niet op Windows, dus kan het ook niet eenvoudig testen voor je...

Acties:
  • 0 Henk 'm!

  • leuk_he
  • Registratie: Augustus 2000
  • Laatst online: 15-07 15:35

leuk_he

1. Controleer de kabel!

http://www.chilkatsoft.com/p/p_499.asp

Werkt system.load met het volledige path toevallig wel?

Need more data. We want your specs. Ik ben ook maar dom. anders: forum, ff reggen, ff topic maken
En als je een oplossing hebt gevonden laat het ook ujb ff in dit topic horen.


Acties:
  • 0 Henk 'm!

  • flux_w42
  • Registratie: November 2006
  • Laatst online: 07-09-2024

flux_w42

jah, nu is het helemaal kapot

Topicstarter
@MikeN: Ik gebruik Code::Blocks met de GNU gcc compiler (MinGW). Blijkbaar was het een linker probleem :D
When compiling, add "--add-stdcall-alias" to your linker flags. If you're passing linker flags via g++, it should be "-Wl,--add-stdcall-alias". This adds an undecorated alias for the exported function names that is simply the name of the function. By default, the functions are exported with an @nn appended to the function name.
Als ik m'n linker "-Xlinker --add-stdcall-alias" meegeef, exporteert hij de functie twee maal, 1x met @nn aan het einde van de method naam en 1x zonder. Nu kan ik m'n dll wel gebruiken via JNI 8) Wooot! Tnx.

Nu ziet m'n dll er zo uit:

Afbeeldingslocatie: http://home.scarlet.be/~jm375900/jnitest/jni_dependency_walker_fixed.png

@leuk_he: Bedankt voor de tip, maar het vinden van de dll zelf was geen probleem. Dat werkte 100% zeker.

Acties:
  • 0 Henk 'm!

Verwijderd

Als je JNI probeert om gewoon is te kijken raad ik je aan om ook is naar JNA te kijken. Tenzij je hele stricte requirements hebt (geen third party libraries etc.) zou ik je JNA aanraden boven JNI. Het werkt een stuk eenvoudiger.

Acties:
  • 0 Henk 'm!

  • flux_w42
  • Registratie: November 2006
  • Laatst online: 07-09-2024

flux_w42

jah, nu is het helemaal kapot

Topicstarter
JNA heb ik al vaak gebruikt en dat werkt super zonder ook maar 1 letter c te moeten schrijven :P. De third part library die ik wil gebruiken verwacht constant polling tijdens een taak, en moet ergens in een main-loop gehouden worden. Dat lukt volgen mij niet met JNA, om dat daar het principe van 'call and return' geldt. Vandaar dat ik nu wat glue code wil schrijven via JNI.
Pagina: 1