Heim  >  Artikel  >  Java  >  Beispiel dafür, wie Java JNA verwendet, um DLL in C# aufzurufen

Beispiel dafür, wie Java JNA verwendet, um DLL in C# aufzurufen

黄舟
黄舟Original
2017-09-08 10:53:452481Durchsuche

Ich habe vor einiger Zeit ein Projekt übernommen, das die Verwendung einer in C# geschriebenen DLL eines Drittanbieters erforderte. Das Projekt selbst ist in der Java-Sprache, daher wurde in diesem Artikel beschrieben, wie das geht Um JNA-Aufrufe in Java zu verwenden, werden wir im Detail anhand von Beispielcodes vorgestellt.

Vorwort

JNA (Java Native Access) bietet eine Reihe von Java-Toolklassen für den dynamischen Zugriff auf die native Bibliothek des Systems während der Laufzeit: Wie z Windows-DLL), ohne nativen/JNI-Code zu schreiben. Entwickler müssen lediglich die Funktionen und Strukturen der nativen Zielbibliothek in einer Java-Schnittstelle beschreiben, und JNA ordnet die Java-Schnittstelle automatisch der nativen Funktion zu.

Vorteile

Mit JNA können Sie lokale Methoden direkt aufrufen, genau wie normale Java-Methoden. Es ist fast dasselbe wie das direkte Ausführen einer lokalen Methode. Der Aufruf einer lokalen Methode erfordert weder zusätzliche Verarbeitung oder Konfiguration noch redundante Referenzen oder Codierung, was die Verwendung sehr bequem macht. Der größte Vorteil von JNA besteht darin, dass die Zeitverschwendung, das Rad neu zu erfinden, vermieden wird.

Jeder, der JNI verwendet hat, weiß, dass es sich bei JNI um ein sehr ungewöhnliches Design handelt, das den generierten Code importieren muss für Java. Die Header-Datei ist ein aufdringliches Design, sodass die zwangsweise kompilierte Quellcode-DLL nicht von C#

JNA-Beschreibung

Die JNA-Klassenbibliothek verwendet eine kleine lokale Klassenbibliothek, um lokalen Code dynamisch aufzurufen. Programmierer müssen lediglich eine bestimmte Java-Schnittstelle verwenden, um die Struktur und einige grundlegende Eigenschaften der aufzurufenden nativen Codemethode zu beschreiben. Dies spart viel Konfigurations- und Kompilierungscode für die Anpassung an mehrere Plattformen. Weil alle Schnittstellen im von JNA bereitgestellten öffentlichen JAR-Paket aufgerufen werden.

1. Beschreibung der Anforderungen:

Wenn unser Projekt mit c# entwickelt wird, müssen wir später mit dem Java-Team zusammenarbeiten Entwicklungsstadien, von denen einige Die Geschäftslogik wurde mit C# codiert, dann können wir erwägen, Java zu verwenden, um die vorgefertigte C#-DLL aufzurufen und die Anforderungen zu implementieren. Ich bin vor ein paar Tagen bei der Arbeit auf ein solches Problem gestoßen und habe den Entwicklungsprozess aufgeschrieben.

Natürlich ist dies nur eine Hypothese. Nach der Analyse der spezifischen Situation denke ich persönlich, dass eine Umgestaltung des Codes der beste Weg ist...

2 Beschreibung:

Eigentlich verstehe ich die spezifischen Prinzipien nicht ganz, deshalb werde ich einfach auf der Grundlage meines eigenen Verständnisses darüber sprechen und versuchen, einige Ideen herauszuarbeiten.

Da der C#-Code auf der .net-Plattform gehostet wird, kann Java den C#-Code nicht direkt aufrufen, sodass die C++-Middleware das Projekt auf die öffentliche CLR-Laufzeit festlegen und dadurch C# als Referenz aufrufen kann . Entsprechende Methode. Und JNA kann die von C ++ generierte DLL direkt aufrufen, sodass der allgemeine Prozess reibungslos verläuft. C++ ruft die geschriebene C#-DLL auf, und Java ruft dann die von C++ generierte DLL-Middleware auf. Der allgemeine Prozess ist wie folgt, es gibt jedoch viele Fallstricke, auf die ich weiter unten näher eingehen werde.

3. Laufplattform:

System: Windows 10 x64

Entwicklungstools: Visual Studio 2015/2017 (I Ich habe verschiedene Versionen implementiert, die auf Laptops und Firmencomputern installiert sind) MyEclipse2014

SDK: jdk-x86, jdk-x64 (DLL ist in x86- und x64-Plattformen unterteilt, und die Version von jdk muss demselben Computer entsprechen. Die beiden Versionen von JDK sind ziemlich nervig. Ich verwende die Systemkonfiguration jdk32-bit, um 32-Bit-DLL zu debuggen, und dann kommt Myeclipse mit 64-Bit-JDK, um 64-Bit-DLL zu debuggen)

4. Vorbereitung:

1. Bereiten Sie zunächst die oben genannte Betriebsplattform vor. Es wird empfohlen, ein JDK mit der gleichen Anzahl von Ziffern wie das System zu wählen (install vs, myeclipse). oder Eclipse oder STS);

2. JNA.jar herunterladen: JNA herunterladen (jna-4.4.0.jar und jna-platform-4.4.0 herunterladen), Sie können es auch lokal herunterladen

5. CODE starten

5.1 c#DLL generieren

 5.1.1 Als Administrator starten (der Das Projekt beinhaltet die Registrierung von COM-Komponenten und muss zum Abschluss als Administrator gestartet werden.) Erstellen Sie ein neues C#-Projekt

5.1.2 Richten Sie zunächst ein C#-Projekt ein

, klicken Sie mit der rechten Maustaste auf das neu erstellte Invoke-Projekt und klicken Sie auf Eigenschaften.

Fahren Sie mit dem Festlegen der Projekteigenschaften fort.

Denken Sie daran zu speichern.

Erstellen Sie dann den CSharp-Klassencode, der aufgerufen werden muss. Hier erstellen wir einige einfache Methoden, um den Effekt zu demonstrieren, indem wir jeweils mit int, string und bool arbeiten. Wie im Bild gezeigt:

Klicken Sie dann mit der rechten Maustaste auf das Projekt und klicken Sie auf „Generieren“.

Schritt eins, erledigt, gut gemacht.

5.2 C++-Middleware generieren

 5.2.1 Erstellen Sie ein neues C++-Projekt und legen Sie Eigenschaften fest.

 Projekt, Eigenschaften auswählen.

 

 5.2.2 C++-Code schreiben

CPP-Datei hinzufügen

 

>  

Bearbeiten Sie die CPP-Datei

Okay, alle C++- und C#-Arbeiten sind abgeschlossen. Klicken Sie zum Generieren mit der rechten Maustaste.

Kopieren Sie den vollständigen Namen der DLL-generierten Datei und verwenden Sie ihn später in Java.

6. Java-Code schreiben

6.1 Erstellen Sie ein neues Java-Projekt und stellen Sie sicher, dass Sie ein JDK auswählen, das mit diesem konsistent ist die DLL-Plattform. Laden Sie dann die beiden zuvor heruntergeladenen JNA-JARs in das Projekt, wie in der Abbildung gezeigt:

6.2 Beginnen Sie mit dem Schreiben von Java-Code

Dann führen wir aus:

Oh, es wird ein Fehler gemeldet [Ungültiger Speicherzugriff], weil Java die C++-DLL gefunden hat, aber nicht die C#-DLL unter Sie können den vollständigen Pfadnamen, den wir für die C++-DLL geschrieben haben, direkt finden. So finden Sie die C#-DLL. Die Antwort besteht darin, die C#-DLL in das Bin-Verzeichnis von JDK zu kopieren, damit der JVM sie finden kann. Wie in der Abbildung gezeigt, kopieren wir Invoke.dll in das bin-Verzeichnis von jdk:

 

Dann führen wir Folgendes aus:

 

schön! Häufig verwendete Typen wie int, string und boolean können problemlos übertragen werden, sofern die Typkorrespondenz zwischen verschiedenen Sprachen auf Baidu eingehalten wird.

7. Hinweise

7.1 Java-Fehler: Ausnahme im Thread „main“ java.lang.Error: Ungültiger Speicherzugriff

Mögliche Gründe: 1. c#dll wird nicht in das bin-Verzeichnis von jdk kopiert

2. Die Datentypen zwischen Java und C++ stimmen nicht überein ;

 7.1.2 Java-Fehler: Ausnahme im Thread „main“ java.lang.UnsatisfiedLinkError: Bibliothek „D:vs WorkplaceX86InvokeTestReleaseX86CPPDlls“ konnte nicht geladen werden: Native Bibliothek (win32-x86/D:vs WorkplaceX86InvokeTestReleaseX86CPPDlls.dll) nicht im Ressourcenpfad gefunden ([file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/bin/, file:/G:/My%20Eclipse%20workplace/InvokeCSharpX86Test/Lib/jna-4.4.0.jar, file: /G :/My%20Eclipse%20workplace/InvokeCSharpX86Test/Lib/jna-platform-4.4.0.jar])

Mögliche Gründe:

 1. Der c++dll-Pfad ist falsch Es wird empfohlen, beim Testen den absoluten Pfad zu verwenden, damit Sie ihn nach dem Kompilieren des C++-Projekts direkt im Java-Programm aufrufen können.

2. Die Plattform von jdk stimmt nicht mit der Plattform von überein Das C++-Projekt ist 32-Bit, daher muss die C++-DLL 32-Bit sein, und das Gleiche gilt für 64-Bit.

7.1.3 Die 32-Bit-DLL, die unter Windows 64 kompiliert wurde. Bit hat den Test nicht bestanden. Ich weiß nicht, ob es am 64-Bit-System liegt, da die virtuelle Maschine meines Computers nicht über diese verfügt. Nach der Installation habe ich es nicht auf einem 32-Bit-System getestet.

Zusammenfassung

Das obige ist der detaillierte Inhalt vonBeispiel dafür, wie Java JNA verwendet, um DLL in C# aufzurufen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn