JNI: UnsatisfiedLinkError: ne Peut pas trouver de bibliothèques dépendantes
Je suis en train d'écrire un programme Java simple qui appelle une fonction C via JNI imprimer "Bonjour le Monde". Tout se compile sans erreur, mais quand je lance le programme, j'obtiens un "UnsatisfiedLinkError: ne Peut pas trouver de bibliothèques dépendantes".
Selon Dependency Walker et dumpbin, la seule dépendance est "kernel32.dll" en C:\Windows\System32 et de ses dépendances, également dans System32.
Appel
System.loadLibrary("Kernel32");
renvoie à aucune erreur, mais le chargement de la Hello.dll qui contient la fonction d'impression en jette toujours une erreur.
Personne ne sait ce qui pourrait en être la cause?
EDIT:
Dependency Walker ne donner que deux avertissements/erreurs:
-Erreur: Au moins un module a un suspens à l'importation dus à une exportation manquante de la fonction implicitement module dépendant.
-Erreur: les Modules avec différents types de processeurs ont été trouvés.
EDIT:
Voici quelques détails supplémentaires: je suis sous Windows 7 64 bits, et la compilation de mon .dll avec cl (Visual Studio 2010).
Mon code Java Hello.java:
public class Hello
{
public static native void hello();
public static void main(String[] args)
{
hello();
}
static
{
//Extra dependencies load with no error
System.loadLibrary("NTDLL");
System.loadLibrary("KERNELBASE");
System.loadLibrary("KERNEL32");
System.loadLibrary("Hello"); //Throws UnsatisfiedLinkError
}
}
Je peux compiler le fichier java avec aucune erreur, et l'utilisation javah -jni pour générer un en-tête C Bonjour.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Hello */
#ifndef _Included_Hello
#define _Included_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Hello
* Method: hello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Hello_hello
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
- Je mettre en œuvre l'en-tête dans Bonjour.c:
#include <stdio.h>
#include <jni.h>
#include "Hello.h"
#pragma comment(linker, "/EXPORT:Java_Hello_hello=_Java_Hello_hello@8")
JNIEXPORT void JNICALL
Java_Hello_hello(JNIEnv* env, jclass class)
{
printf("Hello World\n");
return;
}
Le code C est compilé avec la cl (bien que j'ai aussi essayé de stc) en Hello.dll, qui est stocké dans le même répertoire que le java .classe
- Cela fonctionne si vous passez
-Djava.library.path=C:\Windows\System32
comme un argument de ligne de commande pourjava
? - Avez-vous un exemple de code? Le fichier d'en-tête
javah
fait serait utile aussi. - Y compris System32 en java.de la bibliothèque.chemin jette la même erreur.
Vous devez vous connecter pour publier un commentaire.
Il semble que mon problème était la combinaison d'un système 64 bits et l'installation de java et 32 bits compilateur C.
Par défaut, Visual C++
cl
compilateur génère des applications 32 bits, et cela a provoqué une erreur lors de la charge par la version 64 bits de java. J'ai compilé mon application avec le SDK Windows 7.1 compilateur 64 bits, et il a fonctionné sans erreur, ainsi que de supprimer les mises en garde de Dependency Walker.J'ai essayé de faire JNI de travailler pour un projet de fin d'école, et qui finit à la recherche d'alternatives au bout d'un mois de s'en cogner la tête. Essayez Java Accès Natif à la place. Il permet d'appeler une fonction C à partir de la bibliothèque partagée sur Windows (.dll) et Linux (.donc), et il a même des méthodes pratiques pour certaines fonctions Win32. Compiler votre code natif dans une librairie partagée, puis utilisez JNA pour lier dynamiquement à la bibliothèque et appelez vos fonctions. Il dit qu'il est significativement plus lent que JNI, ce qui est logique, parce que tout est chargée dynamiquement, mais j'ai remarqué pas les performances.
Pour comprendre comment les compilateurs C marquer vos noms de fonction – tourner
strlen
en_strlen@4
ou quelque chose – je recommande DLL Export Viewer (le lien de téléchargement est en bas). Je ne sais pas si Linux a un outil similaire.vous devrez soit