JNI %1 不是有效的 Win32 应用程序 [英] JNI %1 is not a valid Win32 application

查看:129
本文介绍了JNI %1 不是有效的 Win32 应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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)

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

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)

我安装了 Cygwin64 和 Cygwin32.使用 Cygwin64,我能够从我的 C/C++ 动态库项目生成一个 64 位 DLL.但是,当我调用 System.load("path/to/JNITest.dll") 时,我得到:

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:

Exception in thread "main" java.lang.UnsatisfiedLinkError: C:UsersAndrewDocumentsNetBeansProjectsJNITestLibdistJNITest.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 位 JVM.

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 位版本的 Cygwin 编译并运行时,我得到

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

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

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

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.

如果有任何见解,我将不胜感激!

I'd appreciate any insight!

这里是包含的文件

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

=== 生成的 javah 头文件 (jnitest_JNITest.h) ===

=== Generated javah 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) ===

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

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

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

}

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

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:

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

进一步挖掘发现,这里ClassLoader读取libs.size()时抛出错误:

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

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

答案!

终于明白了.

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

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

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

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

Java_jnitest_JNITest_doHello

代替

Java_jnitest_Main_doHello

更改后,它起作用了!

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

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

推荐答案

终于想通了.

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

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

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

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

Java_jnitest_JNITest_doHello

代替

Java_jnitest_Main_doHello

更改后,它起作用了!

这篇关于JNI %1 不是有效的 Win32 应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆