Maison  >  Article  >  Java  >  Exemple de la façon dont Java utilise jna pour appeler une DLL en C#

Exemple de la façon dont Java utilise jna pour appeler une DLL en C#

黄舟
黄舟original
2017-09-08 10:53:452592parcourir

J'ai entrepris un projet il y a quelque temps, qui nécessitait l'utilisation d'une dll écrite en C# fournie par un tiers. Le projet lui-même est en langage Java, c'est pourquoi l'article suivant a été rédigé. pour utiliser les appels jna en Java. Les informations pertinentes sur les DLL en C# sont présentées en détail à travers un exemple de code. Les amis dans le besoin peuvent s'y référer.

Préface

JNA (Java Native Access) fournit un ensemble de classes d'outils Java pour accéder dynamiquement à la bibliothèque native du système pendant l'exécution : telles que DLL de Windows) sans écrire de code Natif/JNI. Les développeurs n'ont qu'à décrire les fonctions et les structures de la bibliothèque native cible dans une interface Java, et JNA mappera automatiquement l'interface Java à la fonction native.

Avantages

JNA vous permet d'appeler des méthodes locales directement comme si vous appeliez des méthodes Java normales. C'est presque la même chose que l'exécution directe d'une méthode locale, et l'appel d'une méthode locale ne nécessite pas de traitement ou de configuration supplémentaire, ni de références ou de codage redondants. Il est très pratique à utiliser. Le plus grand avantage de JNA est qu'il évite la perte de temps liée à la réinvention de la roue.

Tous ceux qui ont utilisé JNI savent que JNI est une conception très anormale qui doit importer le code généré spécifiquement. pour Java. Le fichier d'en-tête est une conception intrusive, de sorte que la dll compilée du code source modifié de force ne sera pas appelée par C#

Description JNA

La bibliothèque de classes JNA utilise une petite bibliothèque de classes locale pour appeler dynamiquement le code local. Les programmeurs n'ont besoin que d'utiliser une interface Java spécifique pour décrire la structure et certaines propriétés de base de la méthode de code natif à appeler. Cela permet d'économiser beaucoup de code de configuration et de compilation pour s'adapter à plusieurs plateformes. Parce que toutes les interfaces du package jar public fourni par JNA sont appelées.

1. Description des exigences :

Si notre projet est développé en C#, nous devrons coopérer avec l'équipe Java ultérieurement. étapes de développement, dont certaines La logique métier a été codée en C#, nous pouvons alors envisager d'utiliser Java pour appeler la dll C# prête à l'emploi afin d'implémenter les exigences. Il m'est arrivé d'avoir rencontré un tel problème au travail il y a quelques jours, j'ai donc noté le processus de développement.

Bien sûr, ce n'est qu'une hypothèse. Après avoir analysé la situation spécifique, je pense personnellement que refactoriser le code est le meilleur moyen...

2. description :

En fait, je ne comprends pas très bien les principes spécifiques, donc je vais juste en parler en fonction de ma propre compréhension et essayer de tirer quelques idées.

Étant donné que le code C# est hébergé sur la plate-forme .net, Java ne peut pas appeler directement le code C#, donc un middleware C++ est introduit. Le projet C++ peut définir le projet sur le runtime public clr, appelant ainsi C# par référence. . Méthode correspondante. Et jna peut appeler directement la DLL générée par C++, donc le processus général est fluide. C++ appelle la dll c# écrite, et java appelle ensuite le middleware dll généré par c++. Le processus général est le suivant, mais il existe de nombreux pièges, que je développerai ci-dessous.

3. Plateforme d'exécution :

Système : Windows 10 x64

Outils de développement : Visual Studio 2015/2017 (I J'ai implémenté différentes versions installées sur les ordinateurs portables et les ordinateurs de l'entreprise) MyEclipse2014

SDK : jdk-x86, jdk-x64 (la dll est divisée en plateformes x86 et x64, et la version de jdk doit correspondre au même ordinateur. Les deux versions de jdk sont assez ennuyeuses. J'utilise la configuration système jdk32-bit pour déboguer la dll 32 bits, puis myeclipse est livré avec un jdk 64 bits pour déboguer la dll 64 bits)

4. Préparation :

1. Préparez d'abord la plateforme d'exploitation mentionnée ci-dessus. Il est recommandé de choisir un jdk avec le même nombre de chiffres que le système (installer. vs, myeclipse ou eclipse ou sts) ;

2. Téléchargez jna.jar : téléchargement JNA (téléchargez jna-4.4.0.jar et jna-platform-4.4.0), vous pouvez également le télécharger localement

5. Démarrer CODE

5.1 Générer c#DLL

 5.1.1 Démarrer vs as administrateur (le projet implique l'enregistrement de composants com et doit être démarré en tant qu'administrateur pour le terminer), Créer un nouveau projet c#

5.1.2 Mettre en place un projet c#

Tout d'abord, cliquez avec le bouton droit sur le projet Invoke nouvellement créé et cliquez sur Propriétés.

Continuez à définir les propriétés du projet.

N'oubliez pas d'enregistrer.

Créez ensuite le code de la classe CSharp qui doit être appelé. Ici, nous créons quelques méthodes simples. Afin de démontrer l'effet, nous opérons respectivement sur int, string et bool. Comme le montre l'image :

Cliquez ensuite avec le bouton droit sur le projet et cliquez sur Générer.

Première étape, c'est fait, bravo.

5.2 Générer un middleware C++

 5.2.1 Créez un nouveau projet C++ et définissez les propriétés

 Projet, sélectionnez les propriétés.

 

 5.2.2 Écrire du code C++

Ajouter un fichier cpp

 

>  

Modifiez le fichier cpp

D'accord, tout le travail C++ et C# est terminé, faites un clic droit pour générer.

Copiez le nom complet du fichier dll généré et utilisez-le en Java plus tard.

6. Écrivez du code Java

6.1 Créez un nouveau projet Java et assurez-vous de sélectionner un jdk cohérent avec la plateforme dll. Chargez ensuite les deux jars jna téléchargés auparavant dans le projet, comme indiqué dans la figure :

6.2 Commencez à écrire du code java

Ensuite, nous exécutons :

Oh, une erreur a été signalée [Invalid Memory Access], car Java a trouvé la dll c++, mais n'a pas trouvé la dll c# parmi. eux, le nom de chemin complet que nous avons écrit pour la dll c++ peut être trouvé directement, alors comment trouver la dll c#. La réponse est de copier la dll c# dans le répertoire bin de jdk, et le jvm pourra la trouver. Comme le montre la figure, nous copions Invoke.dll dans le répertoire bin de jdk :

 

Puis exécutons :

 

sympa ! Les types couramment utilisés tels que int, string et boolean peuvent être transférés en douceur. En fait, d'autres types peuvent également être implémentés, à condition que la correspondance de type entre les différentes langues soit respectée. La relation de type spécifique peut être trouvée sur Baidu.

7. Notes

Erreur Java 7.1 : Exception dans le fil "main" java.lang.Erreur : Accès mémoire non valide

Raisons possibles : 1. c#dll n'est pas copié dans le répertoire bin de jdk

2. Les types de données entre java et c++ ne correspondent pas ; ;

 Erreur Java 7.1.2 : Exception dans le thread "main" java.lang.UnsatisfiedLinkError : Impossible de charger la bibliothèque 'D:vs WorkplaceX86InvokeTestReleaseX86CPPDlls' : Bibliothèque native (win32-x86/D:vs WorkplaceX86InvokeTestReleaseX86CPPDlls.dll) introuvable dans le chemin des ressources ([file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/bin/, file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/Lib/jna-4.4.0.jar, fichier : /G :/My%20Eclipse%20workplace/InvokeCSharpX86Test/Lib/jna-platform-4.4.0.jar])

Raisons possibles :

 1. Le chemin de la dll c++ est incorrect , il est recommandé de faire Utilisez le chemin absolu lors des tests, afin de pouvoir l'appeler directement dans le programme java sans copier après avoir compilé le projet c++

2. La plateforme de jdk ne correspond pas à la plateforme de ; le projet c++ Jdk est en 32 bits, donc c++ + La dll doit être en 32 bits, et il en va de même pour le 64 bits

7.1.3 La dll 32 bits compilée sous windows 64- ; a échoué au test. Je ne sais pas si cela est dû au système 64 bits, car la machine virtuelle de mon ordinateur n'en a pas. Après l'avoir installé, je ne l'ai pas testé sur un système 32 bits.

Résumé

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn