JNI调用

使用JNI的原因,java项目中有时会调用本地方法,如c/c++的方法,采用JNI可以实现,相关实现方式还有JNA,JNative。


JNI的使用方式

  • 在java中声明native方法
package com.test.nativeDemo;

public class NativeTest {
    public static native int add(int a, int b);
}
  • 生成.h(c/c++头文)文
    • javac NativeTest 生成 NativeTest .clas文件
    • 在com的父目录下 运行 javah -jni com.test.nativeDemo.NativeTest 注意一定要在包的父级目录下运行,不然找不到NativeTest这个class
    • 运行完上面命令就会在com的父级目录出现.h
         com_test_nativeDemo_NativeTesh.h
  • 用这个.h文件去visual studio生成dll文件。采用c/c++实现的时候,这个.h文件当作头文件,这个时候需要再dll项目中引入jdk相关dll。

    • 生成dll后,我们在java文件中就可以引入了,将生成的dll文件放到jdk中,具体方法如图:
      这里写图片描述
  • 在java代码中引入dll文件

package com.test.nativeDemo;

public class NativeTest {

    static {
        System.loadLibrary("NativeTest");
    }
    public static native int add(int a, int b);

    public static void main(String[] args) {
        System.out.println(add(1, 2));
    }
}

 注意

  • 以下代码为生成的.h文件内容:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_test_nativeDemo_NativeTest */

#ifndef _Included_com_test_nativeDemo_NativeTest
#define _Included_com_test_nativeDemo_NativeTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_test_nativeDemo_NativeTest
 * Method:    add
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_com_test_nativeDemo_NativeTest_add
  (JNIEnv *, jclass, jint, jint);

#ifdef __cplusplus
}
#endif
#endif

其中 c/c++中如果JNIEnv 显示报错说明你没有引入jdk相关文件,include,/include/win32/bridge这些文件, t特别注意java到c/c++的变量类型的转化与回收。

  • 报java.lang.UnsatisfiedLinkError: no NativeTest in java.library.path这个错,是没有将dll文件放到jdk中

  • 如果生成的dll文件的位数与jdk的位数不同,同样会报java.lang.UnsatisfiedLinkError异常

  • 如果报A fatal error has been detected by the Java Runtime Environment这个错有可能是传入了null值,jni禁止传入null为参数

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章