2012-04-23 17 views
5

Estoy ejecutando Windows XP. Al parecer JNI y UnsatisfiedLinkError van de la mano ... me he dado cuenta de que la mayoría de las veces, el error de vinculador se parece a esto:JNI - InsatisfiedLinkError en el método nativo

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

Pero eso no es mi problema; Java puede encontrar mi DLL. Recibo un error que me hace pensar que el nombre de mi método equivocado:

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

He intentado buscar a una serie de preguntas similares sobre stackoverflow como this one, this one, this one, this one, y this one, pero ninguno de estos métodos han funcionado. También encontré this thread en los foros de Ubuntu donde parece que es exactamente el mismo problema que tengo, pero el que pregunta no dijo cómo arreglaron su propio problema (que realmente apesta). Todas las búsquedas de Google en esto me han dado un error igual al de java.library.path.

Aquí está mi código real.

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); 
    } 

En cm d.exe: (El comando gcc es mi mezcolanza de varios comandos que he encontrado en Internet.)

>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

No he echado un vistazo de cerca a su código, pero ¿ha considerado usar JNA en su lugar? Entonces no tendrías que preocuparte por la enemistad de JNI. – rob

+0

Ni siquiera sabía que JNA existía. Lo miraré. Gracias :) – nuju

+0

¿Cuál es el nombre del paquete que está usando en su código java? – ioums

Respuesta

4

Después de jugar un poco y buscando en Google para resolver el mismo problema durante la mitad del día, tengo descubrió que GCC no genera DLL donde la JVM puede resolver símbolos. Pero uno puede pasar los args de línea de comando correctos a GCC y luego funciona:

Ver this MinGW publicar sobre el tema. Uno necesita pasar "-D_JNI_IMPLEMENTATION_ -Wl, - kill-at" como indicadores adicionales. No sé si todos son necesarios o solo el primer bit.

+1

Usted señor, merece más atención. Pasé medio día tratando de resolverlo. Estaba a punto de hacer una pregunta similar sobre SO cuando vi su respuesta. –

Cuestiones relacionadas