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

 2023-01-19    424  

问题描述

我在64位Windows 8上运行NetBeans,JDK 1.7_25(64位),按照NetBeans开始JNI的说明( https://netbeans.org/kb/kb/docs/cnd/beginning-beginning-jni-linux.html )

)

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

指令适用于linux,但我相信的窗口的原理是相同的(生成.dll文件而不是.so,使用win32包含在jdk中等)

)

我安装了cygwin64以及cygwin32.使用Cygwin64,我能够从C/C ++动态库项目中生成64位DLL.但是,当我调用system.load(“路径/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位JVM.

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

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也是如此.

我感谢任何见解!

编辑:这是其中的文件

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

/* 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");

}

编辑:

问题似乎与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

一些更多的挖掘发现,当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;
    }

编辑:答案!

最终发现了它.

首先,cygwin64出了问题.使用不同的64位C编译器摆脱了无效的Win32应用程序错误.

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

Java_jnitest_JNITest_doHello

而不是

Java_jnitest_Main_doHello

更改后,它可以工作!

(尽管我再也无法回答自己的问题了6个小时…所以Dum de Dum)

推荐答案

最终发现了它.

首先,cygwin64出了问题.使用不同的64位C编译器摆脱了无效的Win32应用程序错误.

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

Java_jnitest_JNITest_doHello

而不是

Java_jnitest_Main_doHello

更改后,它可以工作!

以上所述是小编给大家介绍的JNI %1不是一个有效的Win32应用程序,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对77isp云服务器技术网的支持!

原文链接:https://77isp.com/post/25879.html

=========================================

https://77isp.com/ 为 “云服务器技术网” 唯一官方服务平台,请勿相信其他任何渠道。