0
votes

Eclipse Java Jni, java.lang.unsatisfiedLinkError Chargement DLL

J'ai un problème avec le chargement de la DLL d'imprimante. J'ai un fichier DLL à partir du fabricant de l'imprimante (jniprinterStatusLib.dll). J'ai écrit du code comme le fabricant d'imprimante suggéré. Le code est le suivant:

PRINTER NAME = MY PRINTER
status = -1


2 commentaires

Je pense que si vous modifiez le package pour la classe jniprinterStatus , vous devez également recompiler la DLL non?


Je ne suis pas expert sur JNI et DLL. Mais le fichier dll n'est pas à moi, je reçois le fichier de fabricant d'imprimante peut-être que je peux lui demander.


3 Réponses :


0
votes

Désolé, je voulais en fait écrire un commentaire, mais comme je suis toujours faible sur la réputation, je dois essayer de deviner une réponse.

  • Il ne devrait pas y avoir besoin de recompiler la DLL - ce n'est que du code natif à être invoqué.
  • Le package Java de la classe Chargement de la DLL ne doit pas faire la différence, non plus.

    Vous devez vous occuper de votre architecture système: un fichier DLL de 64 bits échouera dans un JRE 32 bits et vice versa. Assurez-vous que votre architecture JRE correspond à l'architecture DLL.

    Une autre chose à prendre en compte est votre répertoire de travail. Eclipse peut utiliser un répertoire de travail différent de ce que vous avez utilisé lorsque vous avez exécuté votre programme de console.

    Dernier mais surtout, veuillez consulter votre variable Java.Library.Path.

    Cette page pourrait également aider: https://www.chilkatsoft.com/java -LIBLibrary-Windows.asp Je couvre tous les détails.


0 commentaires

0
votes

de la javadoc pour la classe non satisfaitLinkerror ...

jeté si la machine virtuelle Java ne peut pas trouver un approprié Définition de la langue maternelle d'une méthode déclarée indigène.

Cela signifie que la fonction java_com_printer_test_jniprinterstatus_getstatus est introuvable.

Méthode LoadLibrary En classe Java.Lang.System recherche généralement les répertoires répertoriés dans la propriété [Système] "Java.Library.Path". Pour les machines Windows, la valeur de cette propriété est généralement la valeur de la variable d'environnement de chemin.

Donc, je suggère d'imprimer la valeur de cette propriété dans votre code pour voir si elle inclut le répertoire contenant votre DLL. Si ce n'est pas alors vous devez résoudre ce problème, que ce soit en déplaçant la DLL ou en modifiant la variable d'environnement de chemin d'accès ou en lançant votre programme Java avec le -djava.library.path = ... option. Après cela, vous devez vérifier la signature de la méthode native. Walker de dépendance est un outil que j'utilise à mon travail pour y accomplir.

Modifier Ayant relu votre question, je sens que je n'ai pas répondu avec précision votre question, alors laissez-moi ajouter ...

Le comportement par défaut de Eclipse est de copier des fichiers de ressources, tels que des DLL, dans le dossier de sortie. Donc, si vous mettez votre dll dans le dossier src \ com \ imprimante \ Test , il obtiendra copie dans le dossier bin \ com \ imprimante \ test . Je suppose que le répertoire de travail actuel, i.e. . est dans votre "java.library.path", c'est pourquoi cela fonctionne lorsque votre code Java est dans le package par défaut.


2 commentaires

Merci, j'ai vérifié le chemin de la bibliothèque et je pense que c'est correct, il y a le répertoire contenant la DLL. J'ai utilisé la dépendance Walker et le nom de la fonction est Java_jniprinterStatus_getStatus. Donc, le problème est vraiment le nom de la fonction DLL? Dois-je ajouter la classe aux packages par défaut pour utiliser cette DLL? La DLL n'est pas la mienne que j'ai besoin de contacter le fabricant. Maintenant, j'utilise la réflexion pour importer la classe à partir du package par défaut, cela fonctionne, mais je pense que ce n'est pas très bon.


Je confirme le chemin . est dans le chemin de la bibliothèque et ce répertoire contient le fichier DLL. Mais le problème avec le nom de la fonction DLL reste. C'est correct?



0
votes

Le paquet attendu des classes Java est codé dur dans la bibliothèque JNI. Dans votre cas, c'est le package par défaut.

Permettez-moi de se développer sur cela. Lorsque l'on met en œuvre une méthode native dans une bibliothèque JNI, il faut créer une fonction C Public C avec un nom dans le format suivant: xxx

En d'autres termes, la bibliothèque JNI peut Il fournit des méthodes pour les classes des forfaits arbitraires - uniquement pour les classes dans des packages que les auteurs de la bibliothèque JNI avaient à l'esprit.

Dans votre cas, c'est la valeur par défaut. La fonction c va java_jniprintererstatus_getstatus . Si vous appelez votre classe myprinterstatus ou placez-le dans le package com.foobar , le temps d'exécution JNI ne pourra pas associer la fonction C avec le Java déclaré déclaré méthode. C'est juste comment JNI a été conçu.


0 commentaires