Java Native Method,出错了

标签 java c++ exception java-native-interface native

我今天刚刚尝试学习 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);

}

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\8.2\executor-snippets\run.xml:53: Java returned: 1

我知道这可以仅通过 java 代码轻松实现,但我正在尝试使用 native 方法,这样我也可以在我的其他 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 methodJava programming with JNI但总是以这个错误结束。

请帮忙解释一下这个异常是怎么回事。

谢谢你:)

最佳答案

是的!经过太多的测试,我终于得到了答案。完整的代码在中,上面片段中的问题是我没有考虑创建头文件的包..(呵呵...我的错误。抱歉为此)

更新的代码片段是:

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

学习了关于不跳过包名称来创建头文件的好章节。

谢谢 @Andrew S@Sergey快速响应。 :)

关于Java Native Method,出错了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45985093/

相关文章:

c++ - 遍历字符串 vector ,从控制台获取输入,给出段错误

Java 相当于 CLR 的 UnhandledException 事件

c# - 在 C# 中生成自定义异常

java - jdk7 32位windows版下载

java - Java 类路径中的点 (.) 有什么作用?

c++ - 具有历史的搜索结构(持久性)

php - $e 在 PHP 异常中

java - 通过构造函数发布对象

java - 如何使用 liberty.java 将 Watson Conversation 连接到我的 web 应用程序 (github)?

c++ - LevelDB:比较器、block_cache 和 filter_policy 的生命周期和职责?