java जेएनआई% 1 वैध Win32 अनुप्रयोग नहीं है



dll jni (1)

आखिरकार इसे समझ लिया

सबसे पहले, साइगविन 64 में कुछ गलत था एक अलग 64-बिट सी कंपाइलर का उपयोग करने से वैध win32 अनुप्रयोग त्रुटि नहीं छीन ली।

दूसरे, मेरी JNITest.c फ़ाइल की विधि हस्ताक्षर गलत था। इसे होना चाहिए था:

Java_jnitest_JNITest_doHello

के बजाय

Java_jnitest_Main_doHello

इसे बदलने के बाद, यह काम करता है!

मैं NetBeans ( https://netbeans.org/kb/docs/cnd/beginning-jni- के साथ शुरुआती जेएनआई) के निर्देशों का पालन करते हुए 64 बिट विंडोज 8 पर नेटबीन्स चला रहा हूं, जेडीके 1.7_25 (64-बिट) के साथ, linux.html )

निर्देश लिनक्स के लिए हैं, लेकिन सिद्धांत विंडोज के लिए समान है I विश्वास (एक .dll फ़ाइल को पैदा करने के बजाय। इसलिए, Win32 का उपयोग करते हुए JDK आदि में शामिल होता है)

मेरे पास साइगविन 64 और साथ ही साइगविन 32 है। सिगविन 64 का उपयोग करके, मैं अपने सी / सी + + डायनेमिक लाइब्रेरी प्रोजेक्ट से 64-बिट डीएलएल जेनरेट करने में सक्षम हूं। हालांकि, जब मैं System.load ("path / to / JNITest.dll") को कॉल करता हूं, तो मुझे मिलता है:

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

मैं जो इकट्ठा करता हूं, यह 32-बिट वर्चुअल मशीन पर 64-बिट अनुप्रयोग लोड करते समय सबसे अधिक बार होता है, लेकिन मेरा netbeans.conf 64-बिट जेवीएम की ओर इशारा कर रहा है।

इसके अतिरिक्त, जब मैं चीजों को संकलित करने और चलाने के लिए साइगविन के 32-बिट संस्करण का उपयोग करता हूं, तो मुझे मिलता है

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

मुझे पूरा यकीन है कि मैं सही ढंग से DLL फ़ाइल उत्पन्न कर रहा हूं, यह जेएनआई ट्यूटोरियल का पालन करने के लिए सिर्फ एक सरल हैलोवाल्ड printf है मैं जेएनआई और सी के लिए बहुत नया हूँ, इसलिए मुझे वाकई यकीन नहीं है कि डीबगिंग कब शुरू करना है सबसे अच्छा मैंने किया है दोनों 32 और 64-बिट DLLs की कोशिश की, और मैंने सुनिश्चित किया है कि मेरा सी संकलक (साइगविन) 64-बिट है, और मेरा JVM भी है

मैं किसी भी अंतर्दृष्टि की सराहना करता हूँ!

संपादित करें: यहां शामिल फ़ाइलें हैं

=== जावा (जेएनआईटीईस्ट.जावा) ===

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();
}

=== उत्पन्न जेवर हैडर (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

=== सी (जेएनआईटीईस्ट सी) ===

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

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

}

संपादित करें:

समस्या DLL के साथ प्रतीत होती है, क्योंकि मैं अन्य 64-बिट DLLs को ठीक से लोड कर सकता हूं। मैंने सोचा कि साइगविन समस्या हो सकती है, इसलिए मैंने अपने कंपाइलर को मिनजीडब्ल्यू-वाई 64 में बदल दिया। यह ठीक संकलित, और पुस्तकालय लोड करता है, लेकिन अब मुझे एक नया अपवाद मिलता है:

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

कुछ और खुदाई में यह पाया गया कि क्लास लोडर libs.size () यहां पढ़ता है जब त्रुटि फेंक दी जाती है:

// 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;
    }

संपादित करें: जवाब!

आखिरकार इसे समझ लिया

सबसे पहले, साइगविन 64 में कुछ गलत था एक अलग 64-बिट सी कंपाइलर का उपयोग करने से वैध win32 अनुप्रयोग त्रुटि नहीं छीन ली।

दूसरे, मेरी JNITest.c फ़ाइल की विधि हस्ताक्षर गलत था। इसे होना चाहिए था:

Java_jnitest_JNITest_doHello

के बजाय

Java_jnitest_Main_doHello

इसे बदलने के बाद, यह काम करता है!

(हालांकि मैं अपने स्वयं के प्रश्न का जवाब 6 घंटे तक नहीं कर सकता ... इसलिए डम डे डम)





unsatisfiedlinkerror