Java JNI %1 不是有效的 Win32 应用程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18194811/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:11:53  来源:igfitidea点击:

JNI %1 is not a valid Win32 application

javadlljava-native-interface64-bitunsatisfiedlinkerror

提问by hotforfeature

I'm running Netbeans on 64-bit Windows 8, with JDK 1.7_25 (64-bit), following the instructions for the Beginning JNI with NetBeans (https://netbeans.org/kb/docs/cnd/beginning-jni-linux.html)

我正在使用 JDK 1.7_25(64 位)在 64 位 Windows 8 上运行 Netbeans,遵循使用 NetBeans 的 Beginning JNI 的说明(https://netbeans.org/kb/docs/cnd/beginning-jni- linux.html)

The instructions are for linux, but the principle is the same for Windows I believe (generating a .dll file instead of .so, using win32 includes in the JDK, etc)

这些说明适用于 linux,但我相信 Windows 的原理是相同的(生成 .dll 文件而不是 .so,使用 JDK 中包含的 win32 等)

I have Cygwin64 installed as well as Cygwin32. Using Cygwin64, I'm able to generate a 64-bit DLL from my C/C++ Dynamic Library project. However, when I call System.load("path/to/JNITest.dll"), I get:

我安装了 Cygwin64 和 Cygwin32。使用 Cygwin64,我能够从我的 C/C++ 动态库项目生成一个 64 位 DLL。但是,当我调用 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

From what I gather, this is most often the case when loading a 64-bit application on a 32-bit virtual machine, but my netbeans.conf is pointing to a 64-bit JVM.

据我所知,在 32 位虚拟机上加载 64 位应用程序时最常见的情况是,但我的 netbeans.conf 指向的是 64 位 JVM。

Additionally, when I use the 32-bit version of Cygwin to compile things and run, I get

此外,当我使用 32 位版本的 Cygwin 编译并运行时,我得到

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

I'm pretty sure I'm correctly generating the DLL file, it's just a simple HelloWorld printf to follow the JNI tutorial. I'm very new to JNI and C, so I'm not really sure where to start debugging. The best I've done is tried both 32 and 64-bit DLLs, and I've made sure my C compiler (Cygwin) is 64-bit, and my JVM is too.

我很确定我正确地生成了 DLL 文件,它只是一个简单的 HelloWorld printf 来遵循 JNI 教程。我对 JNI 和 C 很陌生,所以我不确定从哪里开始调试。我做过的最好的尝试是同时尝试了 32 位和 64 位 DLL,并且我确保我的 C 编译器(Cygwin)是 64 位的,我的 JVM 也是。

I'd appreciate any insight!

我很感激任何见解!

Edit: Here are the included files

编辑:这是包含的文件

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

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

=== Generated javah header (jnitest_JNITest.h) ===

=== 生成的 javah 头文件 (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) ===

=== 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:

编辑:

The problem seems to be with the DLL, since I can load other 64-bit DLLs just fine. I thought that Cygwin might be the problem, so I changed my compiler to MinGW-w64. It compiled fine, and the library loads, but now I get a new exception:

问题似乎出在 DLL 上,因为我可以很好地加载其他 64 位 DLL。我认为 Cygwin 可能是问题所在,所以我将编译器更改为 MinGW-w64。它编译得很好,库加载,但现在我得到一个新的异常:

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

Some more digging found that the error is thrown when ClassLoader reads libs.size() here:

进一步挖掘发现,这里ClassLoader读取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;
    }

Edit: ANSWERS!

编辑:答案!

Finally figured it out.

终于想通了。

Firstly, something was wrong with Cygwin64. Using a different 64-bit C compiler got rid of the not a valid win32 application error.

首先,Cygwin64 有问题。使用不同的 64 位 C 编译器消除了无效的 win32 应用程序错误。

Secondly, my JNITest.c file's method signature was incorrect. It should have been:

其次,我的 JNITest.c 文件的方法签名不正确。本来应该是:

Java_jnitest_JNITest_doHello

Instead of

代替

Java_jnitest_Main_doHello

After changing that, it works!

更改后,它起作用了!

(though I can't answer my own question for another 6 hours... so dum de dum)

(虽然我不能再回答我自己的问题 6 个小时......所以dum de dum)

采纳答案by hotforfeature

Finally figured it out.

终于想通了。

Firstly, something was wrong with Cygwin64. Using a different 64-bit C compiler got rid of the not a valid win32 application error.

首先,Cygwin64 有问题。使用不同的 64 位 C 编译器消除了无效的 win32 应用程序错误。

Secondly, my JNITest.c file's method signature was incorrect. It should have been:

其次,我的 JNITest.c 文件的方法签名不正确。本来应该是:

Java_jnitest_JNITest_doHello

Instead of

代替

Java_jnitest_Main_doHello

After changing that, it works!

更改后,它起作用了!