Java 本机方法,出错了
Java Native Method, gone something wrong
我今天刚尝试在 java 中学习本地方法。我成功加载了 Native.dll
文件,但在方法调用中遇到问题,我也无法弄清楚发生了什么错误。
我的代码片段是:
NativeTest.java
package javaapplication2;
import java.io.File;
import java.util.Scanner;
/**
*
* @author Chirag
*/
public class NativeTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Loading Library nativeLib");
try {
Native n = new Native();
System.out.println("Loading success");
System.out.print("Enter a number to get cube: ");
int x = sc.nextInt();
System.out.println(x + " * " + x + " * " + x + " = " + n.cubecal(x));
} catch (Exception e) {
System.out.println("Error loading native library");
e.printStackTrace();
}
}
}
class Native {
static {
System.setProperty("java.library.path", new File("").getAbsolutePath());
// try {
// Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
// fieldSysPath.setAccessible(true);
// fieldSysPath.set(null, null);
// } catch (Exception e) {
// }
String arch = System.getProperty("sun.cpu.isalist");
if (arch.trim().equalsIgnoreCase("amd64")) {
System.loadLibrary("Native");
} else {
System.loadLibrary("Native");
}
}
public native int cubecal(int x);
}
class 由 javac NativeTest.java
编译
并通过 javah Native
制作 header
文件
Native.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Native */
#ifndef _Included_Native
#define _Included_Native
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Native
* Method: cubecal
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_Native_cubecal
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
还有一张截图
Native.cpp
#include "stdafx.h"
#include "Native.h"
JNIEXPORT jint JNICALL Java_Native_cubecal
(JNIEnv *env, jobject obj, jint val){
return val * val * val;
}
完成所有这些剪辑后,我在执行此代码后收到此错误
Loading Library Native
Loading success
Enter a number to get cube: 4
Exception in thread "main" java.lang.UnsatisfiedLinkError: javaapplication2.Native.cubecal(I)I
at javaapplication2.Native.cubecal(Native Method)
at javaapplication2.NativeTest.main(NativeTest.java:28)
C:\Users\Chirag\AppData\Local\NetBeans\Cache.2\executor-snippets\run.xml:53: Java returned: 1
我知道这可以仅通过 java 代码轻松实现,但我正在尝试使用本机方法,这样我也可以在我的其他 java 项目中利用 C++ 的优势。
Note: I added all relatives path to Project properties in Visual Studio 2012 follows C:\Program Files\Java\jdk1.8.0_144\include
and C:\Program Files\Java\jdk1.8.0_144\include\win32
我也阅读了这些文章Working with java's native method and Java programming with JNI,但总是以这个错误结束。
请帮忙解释一下这个异常是怎么回事。
谢谢:)
是的!经过太多的测试,我终于得到了答案。完整的代码在 package 里面,上面片段的问题是我没有考虑创建头文件的包..(呵呵。 .. 我的错误。抱歉)
更新的代码片段是:
NativeTest.java
package javaapplication2;
import java.io.File;
import java.util.Scanner;
/**
*
* @author Chirag
*/
public class NativeTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Loading library NativeCube");
try {
NativeCube n = new NativeCube();
System.out.println("Loading Library NativeCube succeeded");
System.out.print("Enter a number to get cube: ");
int x = sc.nextInt();
System.out.println(x + " * " + x + " * " + x + " = " + n.cubecal(x));
} catch (Throwable e) {
System.err.println("Error loading library nativeLib: " + e);
e.printStackTrace();
}
}
}
class NativeCube {
public NativeCube() {
System.setProperty("java.library.path", new File("").getAbsolutePath());
System.out.println("Pathes: " + System.getProperty("java.library.path"));
String arch = System.getProperty("sun.cpu.isalist");
if (arch.trim().equalsIgnoreCase("amd64")) {
System.loadLibrary("NativeCube");
} else {
System.loadLibrary("NativeCube_x86");
}
}
public native int cubecal(int x);
}
javah javaapplication2.NativeCube
创建了头文件
javaapplication2_NativeCube.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class javaapplication2_NativeCube */
#ifndef _Included_javaapplication2_NativeCube
#define _Included_javaapplication2_NativeCube
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: javaapplication2_NativeCube
* Method: cubecal
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_javaapplication2_NativeCube_cubecal
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
Main.cpp
#include "javaapplication2_NativeCube.h"
JNIEXPORT jint JNICALL Java_javaapplication2_NativeCube_cubecal
(JNIEnv *env, jobject obj, jint val){
return val * val * val;
}
程序的输出是
Loading library NativeCube
Pathes: C:\Users\Chirag\Documents\NetBeansProjects\JavaApplication2
Loading Library NativeCube succeeded
Enter a number to get cube: 12
12 * 12 * 12 = 1728
学到了关于不跳过包名来创建头文件的好章节。
我今天刚尝试在 java 中学习本地方法。我成功加载了 Native.dll
文件,但在方法调用中遇到问题,我也无法弄清楚发生了什么错误。
我的代码片段是:
NativeTest.java
package javaapplication2;
import java.io.File;
import java.util.Scanner;
/**
*
* @author Chirag
*/
public class NativeTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Loading Library nativeLib");
try {
Native n = new Native();
System.out.println("Loading success");
System.out.print("Enter a number to get cube: ");
int x = sc.nextInt();
System.out.println(x + " * " + x + " * " + x + " = " + n.cubecal(x));
} catch (Exception e) {
System.out.println("Error loading native library");
e.printStackTrace();
}
}
}
class Native {
static {
System.setProperty("java.library.path", new File("").getAbsolutePath());
// try {
// Field fieldSysPath = ClassLoader.class.getDeclaredField("sys_paths");
// fieldSysPath.setAccessible(true);
// fieldSysPath.set(null, null);
// } catch (Exception e) {
// }
String arch = System.getProperty("sun.cpu.isalist");
if (arch.trim().equalsIgnoreCase("amd64")) {
System.loadLibrary("Native");
} else {
System.loadLibrary("Native");
}
}
public native int cubecal(int x);
}
class 由 javac NativeTest.java
并通过 javah Native
header
文件
Native.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Native */
#ifndef _Included_Native
#define _Included_Native
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Native
* Method: cubecal
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_Native_cubecal
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
还有一张截图
Native.cpp
#include "stdafx.h"
#include "Native.h"
JNIEXPORT jint JNICALL Java_Native_cubecal
(JNIEnv *env, jobject obj, jint val){
return val * val * val;
}
完成所有这些剪辑后,我在执行此代码后收到此错误
Loading Library Native
Loading success
Enter a number to get cube: 4
Exception in thread "main" java.lang.UnsatisfiedLinkError: javaapplication2.Native.cubecal(I)I
at javaapplication2.Native.cubecal(Native Method)
at javaapplication2.NativeTest.main(NativeTest.java:28)
C:\Users\Chirag\AppData\Local\NetBeans\Cache.2\executor-snippets\run.xml:53: Java returned: 1
我知道这可以仅通过 java 代码轻松实现,但我正在尝试使用本机方法,这样我也可以在我的其他 java 项目中利用 C++ 的优势。
Note: I added all relatives path to Project properties in Visual Studio 2012 follows
C:\Program Files\Java\jdk1.8.0_144\include
andC:\Program Files\Java\jdk1.8.0_144\include\win32
我也阅读了这些文章Working with java's native method and Java programming with JNI,但总是以这个错误结束。
请帮忙解释一下这个异常是怎么回事。
谢谢:)
是的!经过太多的测试,我终于得到了答案。完整的代码在 package 里面,上面片段的问题是我没有考虑创建头文件的包..(呵呵。 .. 我的错误。抱歉)
更新的代码片段是:
NativeTest.java
package javaapplication2;
import java.io.File;
import java.util.Scanner;
/**
*
* @author Chirag
*/
public class NativeTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Loading library NativeCube");
try {
NativeCube n = new NativeCube();
System.out.println("Loading Library NativeCube succeeded");
System.out.print("Enter a number to get cube: ");
int x = sc.nextInt();
System.out.println(x + " * " + x + " * " + x + " = " + n.cubecal(x));
} catch (Throwable e) {
System.err.println("Error loading library nativeLib: " + e);
e.printStackTrace();
}
}
}
class NativeCube {
public NativeCube() {
System.setProperty("java.library.path", new File("").getAbsolutePath());
System.out.println("Pathes: " + System.getProperty("java.library.path"));
String arch = System.getProperty("sun.cpu.isalist");
if (arch.trim().equalsIgnoreCase("amd64")) {
System.loadLibrary("NativeCube");
} else {
System.loadLibrary("NativeCube_x86");
}
}
public native int cubecal(int x);
}
javah javaapplication2.NativeCube
javaapplication2_NativeCube.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class javaapplication2_NativeCube */
#ifndef _Included_javaapplication2_NativeCube
#define _Included_javaapplication2_NativeCube
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: javaapplication2_NativeCube
* Method: cubecal
* Signature: (I)I
*/
JNIEXPORT jint JNICALL Java_javaapplication2_NativeCube_cubecal
(JNIEnv *, jobject, jint);
#ifdef __cplusplus
}
#endif
#endif
Main.cpp
#include "javaapplication2_NativeCube.h"
JNIEXPORT jint JNICALL Java_javaapplication2_NativeCube_cubecal
(JNIEnv *env, jobject obj, jint val){
return val * val * val;
}
程序的输出是
Loading library NativeCube
Pathes: C:\Users\Chirag\Documents\NetBeansProjects\JavaApplication2
Loading Library NativeCube succeeded
Enter a number to get cube: 12
12 * 12 * 12 = 1728
学到了关于不跳过包名来创建头文件的好章节。