2012-04-23 6 views
5

Ich verwende Windows XP. Offenbar JNI und UnsatisfiedLinkError Hand in Hand gehen ... Ich habe bemerkt, dass die meisten der Zeit, die Linker-Fehler wie folgt aussehen:JNI - UnbefriedigterLinkError bei nativer Methode

java.lang.UnsatisfiedLinkError: no whatever.dll in java.library.path 

Aber das ist nicht mein Problem; Java kann meine DLL finden. Ich erhalte eine Fehlermeldung, die ich denken läßt, ich meine Methode falsch benannt:

java.lang.UnsatisfiedLinkError: NativeTest.nativemethod(lJava/lang/String;)Z 

Ich habe wie this one, bei einer Reihe von ähnlichen Fragen auf Stackoverflow versucht, Blick this one, this one, this one und this one, aber keine dieser Methoden haben funktioniert. Ich fand auch this thread auf den Ubuntu-Foren, wo es genau das gleiche Problem aussieht, das ich habe, aber der Fragesteller hat nicht gesagt, wie sie ihr eigenes Problem behoben haben (was wirklich nervt). Alle Google-Suchen haben mir einen Fehler gegeben, der dem von java.library.path entspricht.

Hier ist mein tatsächlicher Code.

NativeTest.java

class NativeTest 
    { 

    public static native boolean nativemethod (String arg); 

    public static void main (String[] args) 
     { 
     System.out.println(nativemethod("")); 
     System.out.println(nativemethod("012")); 
     } 

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

    } 

NativeTest.h

/* DO NOT EDIT THIS FILE - it is machine generated */ 
#include <jni.h> 
/* Header for class NativeTest */ 

#ifndef _Included_NativeTest 
#define _Included_NativeTest 
#ifdef __cplusplus 
extern "C" { 
#endif 
/* 
* Class:  NativeTest 
* Method: nativemethod 
* Signature: (Ljava/lang/String;)Z 
*/ 
JNIEXPORT jboolean JNICALL Java_NativeTest_nativemethod 
    (JNIEnv *, jclass, jstring); 

#ifdef __cplusplus 
} 
#endif 
#endif 

NativeTest.c

#include <jni.h> 
#include <windows.h> 
#include "NativeTest.h" 

JNIEXPORT jboolean JNICALL Java_NativeTest_nativemethod 
    (JNIEnv* Jenv, jclass Jref, jstring Jarg) 
    { 
    MessageBox(NULL, "text", "title", MB_OK); 
    int len = (*Jenv)->GetStringLength(Jenv, Jarg); 
    return (jboolean)(len > 5); 
    } 

in cm d.exe: (Der Befehl gcc ist mein Sammelsurium verschiedenen Befehle ich im Internet gefunden habe.)

>javac NativeTest.java 

>javah -jni NativeTest 

>gcc -shared -I<jdk_dir>\include -I<jdk_dir>\include\win32 -oNativeTest.dll NativeTest.c -lgdi32 

>java -Djava.library.path=. NativeTest 
Exception on thread "main" java.lang.UnsatisfiedLinkError: NativeTest.nativemethod(Ljava/lang/String;)Z 
     at NativeTest.nativemethod(Native Method) 
     at NativeTest.main(NativeTest.java:8) 

>java NativeTest 
Exception on thread "main" java.lang.UnsatisfiedLinkError: NativeTest.nativemethod(Ljava/lang/String;)Z 
     at NativeTest.nativemethod(Native Method) 
     at NativeTest.main(NativeTest.java:8) 
+1

Ich habe mir Ihren Code nicht genau angesehen, aber haben Sie erwogen, stattdessen JNA zu verwenden? Dann müssten Sie sich keine Sorgen um JNIs Unfreundlichkeit machen. – rob

+0

Wusste nicht einmal JNA existiert. Ich werde es mir ansehen. Danke :) – nuju

+0

Was ist der Paketname, den Sie in Ihrem Java-Code verwenden? – ioums

Antwort

4

Nach Herumspielen und googeln das gleiche Problem für die Hälfte des Tages zu lösen, ich habe festgestellt, dass GCC keine DLLs erzeugt, in denen die JVM Symbole auflösen kann. Aber man kann die richtigen Befehlszeilenargumente an GCC übergeben und dann funktioniert es:

Siehe this MinGW Beitrag zum Thema. Man muss "-D_JNI_IMPLEMENTATION_-Wl, - kill-at" als zusätzliche Flags übergeben. Ich weiß nicht, ob sie alle gebraucht werden oder nur das erste bisschen.

+1

Sie, Herr, verdienen mehr Aufmerksamkeit. Ich verbrachte einen halben Tag damit, es herauszufinden. War kurz davor, eine ähnliche Frage zu SO zu stellen, als ich deine Antwort sah. –

Verwandte Themen