JNA, Aufruf der Funktionen einer dll

tanechka

Bekanntes Mitglied
Hallo zusammen,

ich brauche Hilfe bei dem Einbinden einer .dll. Beim Testen kriege ich eine Fehlermeldung:
"%1ist keine zulässige Win32 Anwendung"

Bis jetzt meine Schritte, eine Erweiterung in der .pom(Maven):
Code:
        <dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna-platform</artifactId>
    <version>5.6.0</version>
    </dependency>

Ein Interface:
Code:
public interface ICav extends Library {    
 
    public static final ICav INSTANCE = (ICav ) Native.load("cav", ICav.class);
    String print();

}
Ein Wrapper:
Code:
public class CavWrapper {  

    static {
        addLibraryPath();
    }

    public static void addLibraryPath() {
        System.setProperty("jna.library.path", System.getProperty ("java.library.path"));
        System.out.println(System.getProperty("jna.library.path"));

        NativeLibrary.addSearchPath("cav", "D:\\");
    }
    
    public String print() {
        String result= ICav.INSTANCE.print();
        return result;
        
    }
Die .dll ist x32bit. Meine installierte Java:
Code:
>java -version
Picked up JAVA_TOOL_OPTIONS: -Djava.vendor='Sun Microsystems Inc.'
openjdk version "11.0.18" 2023-01-17 LTS
OpenJDK Runtime Environment Zulu11.62+18-SA (build 11.0.18+10-LTS)
OpenJDK 64-Bit Server VM Zulu11.62+18-SA (build 11.0.18+10-LTS, mixed mode)
Ich bitte um eure Hilfe.
 
Du nutzt ein 64 Bit Java, dann kannst du keine 32 Bit DLL ansprechen. Nutze ein 32 Bit Java und es könnte dann gehen.

Das ist zumindest mein Verständnis hiervon.
 
Nach meinem Verständnis nicht. Es ist ja etwas wie zwei Systeme. Du hast das 64 Bit Windows System und dann hast Du das "Windows on Windows 64Bit" (WoW64) Subsystem, in dem 32 Bit Anwendungen ausgeführt werden können. Da gibt es keine direkte Interaktion von einem Prozess zur DLL.

Es gibt aber natürlich die Möglichkeit, dass man das in eigene Prozesse packt um dann zwischen den Prozessen zu kommunizieren. So gibt es unter Windows die COM Server. Diese unterstützen sowohl In-Process als auch out-of-process vorgehen und hier wäre dann out-of-process das notwendige Vorgehen. Ist aber schon viel zu lange her, dass ich mich mit sowas beschäftigt habe. Und meine Erfahrung war halt zu reinen 32 Bit Zeiten, so dass ich hier lediglich altes Wissen auf die 32/64 Bit Thematik adaptiere.

COM Clients and Servers - Win32 apps | Microsoft Learn

Das ist aber dann etwas, das man erst einmal bauen müsste. Und dann braucht man den Zugriff. Das geht dann nicht mehr einfach mit JNA sondern man braucht da etwas mehr. Dazu kann man sich mal dieses GitHub Projekt ansehen, das aufzeigt, wie man da einen Proxy zu einem COM Server bauen könnte: kohsuke/jinterop-proxy: Type-safe proxy for J-Interop (github.com)

Das wäre eine Lösung, wie sie unter Windows mit COM/DCOM damals üblich war. Aber das ist ural Technologie! Heutzutage werden Windows Entwickler vermutlich auch eher einen .Net Ansatz fahren. Und ein Java Entwickler könnte zur Not eine kleine 32Bit Java Anwendung bauen, die die Zugriffe auf die DLL Kapselt und die dann vom anderen Java Prozess aufgerufen wird.
Aber noch einmal: Die einfache Lösung ist, auf ein 32 Bit Java zu wechseln. Start die Anwendung mit einem 32 Bit Java und es sollte funktionieren. Da es eine einfache Lösung gibt, sehe ich gerade keinen Sinn, irgend etwas überkompliziertes zu bauen. Und wenn man da was bauen müsste als Java Entwickler, dann baut man etwas mit einem 32Bit Java um das zu kapseln um da dann irgendwie drauf zuzugreifen (RMI oder man greift gar zu einem REST Service? Wird dann aber recht umfangreich und wirkt massiv wie Overkill...)
 
Als kleine Info: Ich stand bei meinem Projekt vor einem ähnlichen Problem. Zwei Versionen meiner Software, eine ältere in 32 Bit und die aktuelle in 64 Bit sollten den selben Service ansprechen. Die Lösung war, die Wrapper DLL einmal in 32 und einmal in 64 Bit bereitzustellen.
 

Zurück
Oben