Question

J'écris du code JNI en C ++ à appeler à partir d'une applet sous Windows XP. J'ai réussi à exécuter l'applet et à charger et à appeler la bibliothèque JNI, allant même jusqu'à l'avoir appelée à appeler des fonctions dans d'autres DLL. Cela fonctionne en configurant la variable d’environnement système PATH pour inclure le répertoire dans lequel se trouvent toutes mes DLL.

Le problème, c’est que j’ajoute un autre appel utilisant une nouvelle DLL externe, et soudainement, lors du chargement de la bibliothèque, un UnsatisfiedLinkError est renvoyé. Le message est le suivant: "La procédure spécifiée est introuvable". Cela ne semble pas être un problème avec une DLL dépendante manquante, car je peux supprimer une DLL dépendante et obtenir un message différent concernant la disparition de la DLL dépendante. D'après ce que j'ai pu trouver en ligne, il apparaît que ce message signifie qu'une implémentation de la fonction Java native est absente de la DLL, mais il est étrange que cela fonctionne correctement sans ce peu de code supplémentaire.

Est-ce que quelqu'un sait ce qui pourrait causer cela? Quels types d'éléments peuvent donner un message "La procédure spécifiée est introuvable" pour un UnsatisifedLinkError?

Était-ce utile?

La solution

J'ai compris le problème. C'était un doozy. Le message " La procédure spécifiée est introuvable " for UnsatisfiedLinkError indique qu’une fonction de la DLL racine ou une dll dépendante est introuvable. La cause la plus probable de cela dans une situation JNI est que la fonction JNI native n'est pas exportée correctement. Mais cela peut apparemment se produire si une DLL dépendante est chargée et que cette DLL manque une fonction requise par son parent.

À titre d'exemple, nous avons une bibliothèque appelée input.dll. L'ordre de recherche de la DLL consiste à toujours rechercher d'abord dans le répertoire de l'application et les répertoires PATH en dernier. Auparavant, nous exécutions toujours les exécutables du même répertoire que input.dll. Cependant, il existe un autre fichier input.dll dans le répertoire système de Windows (qui se trouve au milieu de l'ordre de recherche de la DLL). Ainsi, lorsque j'exécute ce code à partir d'un applet java, si j'inclus le code décrit ci-dessus dans l'applet, ce qui entraîne le chargement de input.dll, il charge le fichier input.dll à partir du répertoire système. Parce que notre code attend certaines fonctions dans input.dll qui n'y sont pas (car il s'agit d'une DLL différente), la charge échoue avec un message d'erreur concernant les procédures manquantes. Non pas parce que les fonctions JNI sont mal exportées, mais parce que la DLL dépendante était incorrecte et qu'elle ne contenait pas les fonctions attendues.

Autres conseils

Il est possible que la DLL ait été générée à l'aide de C ++ (par opposition à C). à moins que vous n'ayez pris soin de faire un extern sur la procédure, c'est une des raisons possibles.

Essayez d’exporter toutes les fonctions de la DLL. Si la liste comprend votre fonction, alors vous êtes bon.

Habituellement, lorsque vous vous connectez à d'autres bibliothèques, vous devez créer un lien vers le fichier .lib approprié. On dirait que vous ne faites pas référence à tous les fichiers de lib dont vous avez besoin. Vérifiez ce qui n'est pas lié et assurez-vous d'ajouter sa bibliothèque à la liste de l'éditeur de liens.

Avez-vous créé la nouvelle DLL externe à l'aide de la procédure JNI standard? C'est-à-dire en utilisant javah et ainsi de suite? Si tel est le cas, je ne suis pas sûr de ce qui ne va pas.

Si ce n'est pas le cas, la procédure que vous essayez d'appeler n'a pas été exportée (comme indiqué par anjanb). Je connais deux manières d'exporter des fonctions: une liste d'exportation distincte et le marquage de fonctions spécifiques avec __declspec (dllexport).

Impossible d'accéder à la variable dans la DLL C ++ à partir de une application C contient un peu plus d'informations sur les DLL.

Compilez votre code c ++ en mode débogage. Ensuite, insérez le DebugBreak (); déclaration où vous souhaitez commencer le débogage. Exécutez le code Java. Lorsque l’instruction DebugBreak () est rencontrée, vous obtenez une fenêtre contextuelle avec un bouton Debug. Clique dessus. Dev Studio s'ouvrira avec votre programme en code machine. Repassez-vous deux fois avec le débogueur et vous devriez pouvoir passer par-dessus votre code source.

Si vous avez résolu tous les problèmes de programmation dans les manuels et les exemples JNI mais que vous obtenez toujours la même erreur de procédure manquante, le problème peut probablement se trouver dans votre variable de chemin. Faites les étapes ci-dessous et exécutez à nouveau:

  1. Assurez-vous de définir la variable JAVA_HOME dans votre dossier JDK (pas JRE car JRE ne contient pas d'en-tête jni). Exemple: Dans le panneau des paramètres de variable d’environnement, définissez var: JAVA_HOME val: C: \ Program Files \ Java \ jdk1.7.0_11
  2. ajoutez % JAVA_HOME% \ bin à votre variable de chemin

Après avoir suivi ces étapes, votre application peut trouver le nom de la procédure jni et des liens vers JNI.dll de la bonne manière. J'espère donc que vous n'obtiendrez plus cette erreur de procédure manquante.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top