[英]JNI C++ DLL - 'UnsatisfiedLinkError: %1 is not a valid Win32 application'
[英]JNI %1 is not a valid Win32 application
我正在使用JDK 1.7_25(64位)在64位Windows 8上运行Netbeans,并遵循以NetBeans开头JNI的说明( https://netbeans.org/kb/docs/cnd/beginning-jni- linux.html )
这些说明适用于linux,但我认为适用于Windows的原理相同(生成.dll文件而不是.so,使用JDK中的win32等生成)
我安装了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
据我所知,这是在32位虚拟机上加载64位应用程序时最常见的情况,但是我的netbeans.conf指向的是64位JVM。
此外,当我使用Cygwin的32位版本进行编译并运行时,我得到
Can't load IA 32-bit .dll on a AMD 64-bit platform
我敢肯定,我正确地生成了DLL文件,这只是遵循JNI教程的简单HelloWorld printf。 我是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
更改之后,它就可以了!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.