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爲參數

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