JNI %1 ist keine zulässige Win32-Anwendung

Ich bin mit Netbeans auf 64-bit Windows 8, mit JDK 1.7_25 (64-bit), Folgen Sie den Anweisungen für die Anfang JNI mit NetBeans (https://netbeans.org/kb/docs/cnd/beginning-jni-linux.html)

Die Anleitungen sind für linux, aber das Prinzip ist das gleiche für Windows glaube ich (die Erzeugung ein .dll-Datei statt .so, mithilfe von win32-umfasst die in der JDK, etc)

Habe ich Cygwin64 installiert sowie Cygwin32. Mit Cygwin64, ich bin in der Lage, generieren Sie eine 64-bit-DLL von meiner C/C++ Dynamische Bibliothek-Projekt. Allerdings, wenn ich Ruf-System.laden("path/to/JNITest.dll"), erhalte ich:

Exception in thread "main" java.lang.UnsatisfiedLinkError: C:\Users\Andrew\Documents\NetBeansProjects\JNITestLib\dist\JNITest.dll: %1 is not a valid Win32 application
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
    at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1957)
    at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1882)
    at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1843)
    at java.lang.Runtime.load0(Runtime.java:795)
    at java.lang.System.load(System.java:1061)
    at jnitest.JNITest.main(JNITest.java:8)
Java Result: 1

Von dem, was ich sammeln, ist dies oft der Fall, wenn das laden eines 64-bit-Anwendung auf einem 32-bit-virtual-machine, aber mein netbeans.conf auf einem 64-bit-JVM.

Zusätzlich, wenn ich die 32-bit-version von Cygwin zu kompilieren und Dinge ausführen, bekomme ich

Can't load IA 32-bit .dll on a AMD 64-bit platform

Ich bin mir ziemlich sicher, dass ich richtig Generierung der DLL-Datei, es ist nur ein einfaches HelloWorld printf Folgen die JNI-tutorial. Ich bin sehr neu in JNI und C, also ich bin nicht wirklich sicher, wo um das Debuggen zu starten. Die beste, die ich habe versucht, sowohl die 32-und 64-bit-DLLs, und ich habe sicher, dass mein C-compiler (Cygwin) ist 64-bit, und meine JVM ist auch.

Ich würde schätzen jede Einsicht!

Edit: Hier sind die enthaltenen Dateien

=== Java (JNITest.java) ===

package jnitest;

public class JNITest {

    public static void main(String[] args) {
        System.out.println("JVM: " + System.getProperty("sun.arch.data.model"));
        System.load("C:\\Users\\Andrew\\Documents\\NetBeansProjects\\JNITestLib\\dist\\JNITest.dll");

        new JNITest().doHello();
    }

    public native void doHello();
}

=== Javah generiert header (jnitest_JNITest.h) ===

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jnitest_JNITest */

#ifndef _Included_jnitest_JNITest
#define _Included_jnitest_JNITest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     jnitest_JNITest
 * Method:    doHello
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_jnitest_JNITest_doHello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

=== C (JNITest.c) ===

#include <jni.h>
#include "jnitest_JNITest.h"

JNIEXPORT void JNICALL Java_jnidemojava_Main_nativePrint
        (JNIEnv *env, jobject obj) 
{
    printf("\nHello World from C\n");

}

Edit:

Scheint das problem zu sein, mit der DLL, da kann ich laden, andere 64-bit-DLLs nur in Ordnung. Ich dachte, dass der Cygwin-das problem sein könnte, also habe ich meinen compiler MinGW-w64. Es kompiliert einwandfrei, und die Bibliothek geladen, aber jetzt bekomme ich eine neue exception:

Exception in thread "main" java.lang.UnsatisfiedLinkError: jnitest.JNITest.doHello()V
    at jnitest.JNITest.doHello(Native Method)
    at jnitest.JNITest.main(JNITest.java:10)
Java Result: 1

Einige mehr Graben gefunden, dass der Fehler ausgelöst wird, wenn ClassLoader liest libs.size() hier:

//Invoked in the VM class linking code.
    static long findNative(ClassLoader loader, String name) {
        Vector<NativeLibrary> libs =
            loader != null ? loader.nativeLibraries : systemNativeLibraries;
        synchronized (libs) {
            int size = libs.size();
            for (int i = 0; i < size; i++) {
                NativeLibrary lib = libs.elementAt(i);
                long entry = lib.find(name);
                if (entry != 0)
                    return entry;
            }
        }
        return 0;
    }

Edit: ANTWORTEN!

Endlich kapiert.

Erstens, etwas war falsch mit Cygwin64. Mit einer anderen 64-bit-C-compiler losgeworden, die keine gültige win32-Anwendung Fehler.

Zweitens, meine JNITest.c-Datei die Signatur der Methode falsch war. Es sollte haben:

Java_jnitest_JNITest_doHello

Statt

Java_jnitest_Main_doHello

Nach der änderung funktioniert es!

(obwohl ich keine Antwort auf meine eigene Frage für weitere 6 Stunden... so dum de dum)

  • Finden Sie ein 64-bit-dll, die Sie nicht selbst erstellen. Funktioniert das? Wenn ja, die dll ist ungültig aus irgendeinem Grund, das können wir später besprechen.
  • Ja, ich habe System.laden("C:\\Windows\\System32\\aaclient.dll"), zufällige 64-bit-dll, bevor das System.laden meiner dll und das hat geklappt. Ich habe noch eine Ausnahme, wenn ich versuchte, laden von mir, obwohl. Ich weiß ehrlich gesagt nicht wissen, etwas über dlls, also ich bin mir nicht sicher, wo zu beginnen, warum es ungültig ist
  • Ich kann dir nicht helfen, denn ich weiß es auch nicht, aber jetzt scheint es nicht mehr ein Java-problem sein und stattdessen C/C++/Win32API/DLL Problem.
  • So denken es könnte der 64-bit-Cygwin-compiler, die ich heruntergeladen habe MinGW64, und kompilieren der dll. Diese Zeit, die Bibliothek lädt, aber ich bin immer: Exception in thread "main" java.lang.UnsatisfiedLinkError: jnitest.JNITest.doHello()V
  • Das scheint, wie es ein header Problem. Hat man sich bei deiner Methode Deklarationen und-definition? Verwirren Sie die Hölle aus mir heraus.
  • Soweit ich weiß .exe und .dll cygwin-Programme sind eigentlich nicht ausführbare windows-Dateien, wie Sie abhängig sind cygwin1.dll kommunizieren zu windows. MinGW, denke ich, generiert windows native ausführbare Dateien.

Schreibe einen Kommentar