首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JNI%1不是有效的Win32应用程序

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

Stack Overflow用户
提问于 2013-08-13 03:10:43
回答 1查看 12.6K关注 0票数 2

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

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

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

代码语言:javascript
复制
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位版本的Cygwin编译和运行程序时,我得到

代码语言:javascript
复制
Can't load IA 32-bit .dll on a AMD 64-bit platform

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

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

编辑:这里是包含的文件

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

代码语言:javascript
复制
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) ===

代码语言:javascript
复制
/* 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) ===

代码语言:javascript
复制
#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。它编译得很好,并且加载了库,但是现在我得到了一个新的异常:

代码语言:javascript
复制
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()时会抛出错误:

代码语言:javascript
复制
// 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文件的方法签名不正确。它应该是:

代码语言:javascript
复制
Java_jnitest_JNITest_doHello

而不是

代码语言:javascript
复制
Java_jnitest_Main_doHello

在改变这一点之后,它就能工作了!

(虽然我在接下来的6个小时内不能回答我自己的问题...所以dum de dum)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-08-13 13:09:41

终于想明白了。

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

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

代码语言:javascript
复制
Java_jnitest_JNITest_doHello

而不是

代码语言:javascript
复制
Java_jnitest_Main_doHello

在改变这一点之后,它就能工作了!

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18194811

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档