![](/img/trans.png)
[英]Intellij - UnsatisfiedLinkError: %1 .dll is no valid win32 application
[英]JNI C++ DLL - 'UnsatisfiedLinkError: %1 is not a valid Win32 application'
在深入研究实际代码之前,我试图让 JNI 真正工作,但是在我从 C++ 编译 DLL 并运行我的 Java 应用程序之后,我得到:
Exception in thread "main" java.lang.UnsatisfiedLinkError: <snip>\workspace\JNI test\native\jnitest.dll: %1 is not a valid Win32 application
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary1(Unknown Source)
at java.lang.ClassLoader.loadLibrary0(Unknown Source)
at java.lang.ClassLoader.loadLibrary(Unknown Source)
at java.lang.Runtime.loadLibrary0(Unknown Source)
at java.lang.System.loadLibrary(Unknown Source)
at net.condorcraft110.jnitest.JNITest.main(JNITest.java:11)
在 Google 上搜索了一下,我知道这通常是由于尝试使用 32 位 JVM 加载 64 位 DLL 引起的。 但是,我的 JVM 是 64 位的,正如sun.arch.data.model
等于 64 所证明的sun.arch.data.model
。
我的生成文件:
CLASSPATH = ../bin
vpath %.class $(CLASSPATH)
all : jnitest.dll
jnitest.dll : jnitest.o
g++ -m64 -Wl,--add-stdcall-alias -shared -o $@ $<
jnitest.o : jnitest.cpp jnitest.h
g++ -m64 -I"C:\Program Files\Java\jdk1.7.0_51\include" -I"C:\Program Files\Java\jdk1.7.0_51\include\win32" -c $< -o $@
jnitest.h : net/condorcraft110/jnitest/JNITest.class
javah -verbose -classpath $(CLASSPATH) -o jnitest.h net.condorcraft110.jnitest.JNITest
clean :
rm jnitest.h jnitest.o jnitest.dll
JNITest.java:
package net.condorcraft110.jnitest;
public class JNITest
{
private static native void test();
public static void main(String[] args)
{
System.out.println("sun.arch.data.model = " + System.getProperty("sun.arch.data.model"));
System.loadLibrary("jnitest");
test();
}
}
由 javah 生成的 jnitest.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class net_condorcraft110_jnitest_JNITest */
#ifndef _Included_net_condorcraft110_jnitest_JNITest
#define _Included_net_condorcraft110_jnitest_JNITest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: net_condorcraft110_jnitest_JNITest
* Method: loadPlugins
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_net_condorcraft110_jnitest_JNITest_test
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
jnitest.cpp:
using namespace std;
#include <jni.h>
#include <iostream>
#include "jnitest.h"
extern "C" JNIEXPORT void JNICALL Java_net_condorcraft110_jnitest_JNITest_test(JNIEnv *env, jclass clazz)
{
cout << "jni test successful" << endl;
}
有谁知道为什么这不起作用?
编辑: java.library.path
绝对指向native
,如在 Eclipse 运行配置中设置的那样。
编辑 2:如果我用 VS2013 编译 DLL,它就可以工作,但如果我能帮上忙,我真的不想将我的项目绑定到 Visual Studio。
对我来说,问题是我新添加的DLL依赖于我不知道的其他DLL。 Windows有帮助地在我的路径中找到了一个32位版本,但无法加载它,因为我的应用程序是64位。
我使用Dependency Walker (有32位和64位版本,以及Itanium ...)和Process Monitor来调试它。 它的长短是确保你的DLL所引入的每个DLL也是64位,你会更开心。
需要注意的一件事是,如果Windows找到一个正确名称的32位DLL,它会尝试加载它,而在Process Monitor中,它看起来就像是在成功读取它。 确保继续向下滚动!! 您可能会发现系统丢弃此DLL并继续搜索64位版本的路径。
更新:
另外两件事要注意:
1)旧的Dependency Walker可能看起来像它加载的DLL不匹配,例如它可能首先找到32位匹配,当你真的想要一个64位DLL,并告诉你有CPU类型不匹配。 刚刚获得新版本,这个问题就消失了。 感谢https://stackoverflow.com/a/22384936/309502获取此信息。
2)加载DLL时,顺序很重要。 我没有意识到我正在以错误的顺序装载其中两个,并且无法弄清楚它为什么不起作用。 检查您是否先加载先决条件。 :-)
我也遇到了同样的问题。 在我的情况下的问题是我的dll采取了一些64位依赖的DLL。 我打开我的jni dll进入依赖walker,在那里我找到了64位dll。 我用32位替换它。 我的问题得到了解决。
我最初得到Can't find dependent libraries
错误,解决了我在路径中添加了DLL的问题。 但这导致我错误%1 is not a valid Win32 application at java
。 为了解决这一切,使静态构建为我工作,编译: g++ -static
。 它在构建本身中添加了依赖库。
我通过将这些 .dll 文件的列表从 Win64_x64 复制到应用程序的 bin/main 目录来解决我的问题,并且应用程序运行成功:
NBiometricClient.dll
NBiometrics.dll
NCore.dll
NDevices.dll
NLicensing.dll
NMedia.dll
NMediaProc.dll
NMMAbisClient.dll
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.