使用 Java 本机接口时出错
Error using Java Native Interface
我正在尝试开发一个使用 C++ 代码的 java 程序。为此,我使用了 32 位 mingw、32 位 jre(版本 1.8.0_77)和 eclipse luna (64 位)。
问题
我在尝试加载 *.dll 时遇到问题。 (我还没有尝试 运行 任何方法)
我测试了什么
这是我声明本机方法的 class:
public class JniImports {
static{
System.loadLibrary("hello");
}
public int test(int n){
return testJava(n);
}
private native int testJava(int n);
}
这是主要方法:
public class Main {
public static void main(String[] args) {
JniImports a = new JniImports();
}
}
我已经在 eclipse 上配置了 JVM 的参数并添加了这个:-Djava.library.path=./jni
c-header 文件已经由javah
工具生成,所以我确定没问题。无论如何,正如我所说,我没有尝试执行任何方法。这里是头文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jnitest_JniImports */
#ifndef _Included_com_jnitest_JniImports
#define _Included_com_jnitest_JniImports
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jnitest_JniImports
* Method: testJava
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_com_jnitest_JniImports_testJava
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
这里是 cpp 文件:
#include "com_jnitest_JniImports.h"
JNIEXPORT jint JNICALL Java_com_jnitest_JniImports_testJava
(JNIEnv *env, jobject _this, jint n){
return 12;
}
这是我用来编译的命令(g++ 是 mingw 32 位):
g++ -Wl,--add-stdcall-alias -I"%JDK32_HOME%\include" -I"%JDK32_HOME%\include\win32" -shared -o hello.dll com_jnitest_JniImports.cpp
错误
如果我使用 64 位 JRE,错误是它无法在 64 位 jre 上加载 32 位 dll:
java.lang.UnsatisfiedLinkError: D:\ws\testjni\jni\hello.dll Can't load IA 32-bit .dll on a AMD 64-bit platform
我认为这个错误表明,在这种情况下,JRE 找到了 *.dll。
如果我使用 32 位 JRE,错误是找不到 *.dll:
java.lang.UnsatisfiedLinkError: D:\ws\testjni\jni\hello.dll: Can't find dependent libraries
如果我使用 32 位 JRE 并删除 hello.dll 库,则会出现以下错误:
java.lang.UnsatisfiedLinkError: no hello in java.library.path
所以,用32位的编译器编译c++代码,用32位的JRE,能找到dll,但还是崩溃了。
我也试过在调试模式下编译 c++ 代码(使用 -g 标志),但它也崩溃了。
我确定 dll 位于正确的位置,因为如果我将错误日志中显示的路径复制粘贴到 window 的资源管理器路径栏中,它会将我带到该文件夹dll 在哪里,我确定它的名称是 "hello.dll".
我已经用最新版本的 eclipse (32 位) 测试了它,它可以工作。我不知道这是一个 eclipse 错误,还是问题是我使用的是 64 位的 eclipse,现在我使用的是 32 位的。
我正在尝试开发一个使用 C++ 代码的 java 程序。为此,我使用了 32 位 mingw、32 位 jre(版本 1.8.0_77)和 eclipse luna (64 位)。
问题
我在尝试加载 *.dll 时遇到问题。 (我还没有尝试 运行 任何方法)
我测试了什么
这是我声明本机方法的 class:
public class JniImports {
static{
System.loadLibrary("hello");
}
public int test(int n){
return testJava(n);
}
private native int testJava(int n);
}
这是主要方法:
public class Main {
public static void main(String[] args) {
JniImports a = new JniImports();
}
}
我已经在 eclipse 上配置了 JVM 的参数并添加了这个:-Djava.library.path=./jni
c-header 文件已经由javah
工具生成,所以我确定没问题。无论如何,正如我所说,我没有尝试执行任何方法。这里是头文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_jnitest_JniImports */
#ifndef _Included_com_jnitest_JniImports
#define _Included_com_jnitest_JniImports
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_jnitest_JniImports
* Method: testJava
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_com_jnitest_JniImports_testJava
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
这里是 cpp 文件:
#include "com_jnitest_JniImports.h"
JNIEXPORT jint JNICALL Java_com_jnitest_JniImports_testJava
(JNIEnv *env, jobject _this, jint n){
return 12;
}
这是我用来编译的命令(g++ 是 mingw 32 位):
g++ -Wl,--add-stdcall-alias -I"%JDK32_HOME%\include" -I"%JDK32_HOME%\include\win32" -shared -o hello.dll com_jnitest_JniImports.cpp
错误
如果我使用 64 位 JRE,错误是它无法在 64 位 jre 上加载 32 位 dll:
java.lang.UnsatisfiedLinkError: D:\ws\testjni\jni\hello.dll Can't load IA 32-bit .dll on a AMD 64-bit platform
我认为这个错误表明,在这种情况下,JRE 找到了 *.dll。
如果我使用 32 位 JRE,错误是找不到 *.dll:
java.lang.UnsatisfiedLinkError: D:\ws\testjni\jni\hello.dll: Can't find dependent libraries
如果我使用 32 位 JRE 并删除 hello.dll 库,则会出现以下错误:
java.lang.UnsatisfiedLinkError: no hello in java.library.path
所以,用32位的编译器编译c++代码,用32位的JRE,能找到dll,但还是崩溃了。
我也试过在调试模式下编译 c++ 代码(使用 -g 标志),但它也崩溃了。
我确定 dll 位于正确的位置,因为如果我将错误日志中显示的路径复制粘贴到 window 的资源管理器路径栏中,它会将我带到该文件夹dll 在哪里,我确定它的名称是 "hello.dll".
我已经用最新版本的 eclipse (32 位) 测试了它,它可以工作。我不知道这是一个 eclipse 错误,还是问题是我使用的是 64 位的 eclipse,现在我使用的是 32 位的。