一 JNI理解
JNI: java native interface
使用環境:
- java api 不能滿足我們程序的需要的時候。
- 算法計算,圖像渲染 效率要求非常高,
- 當需要訪問一些已有的本地庫
NDK:
工具的集合。幫助開放者快速開放C/C++ 動態庫的工具。
二 JNI簡單調用
1 編寫native 方法
public class JniMain {
public static native String getStringFromC();
public native String getStringFromC2();
}
2 javah 命令,生成.h 文件
java_類的全名_方法名
或者自己手寫
JniMai.h
#include "jni.h"
/* Header for class JniMain */
#ifndef _Included_JniMain
#define _Included_JniMain
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JniMain
* Method: getStringFromC
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_bpj_ndk_JniMain_getStringFromC
(JNIEnv *, jclass);
/*
* Class: JniMain
* Method: getStringFromC2
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_bpj_ndk_JniMain_getStringFromC2
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
3. 複製.h 頭文件到cpp 工程
4. 複製jni.h 和jni_md.h(在jdk目錄搜索)
5. 實現.h 頭文件中的聲明函數
#include "stdafx.h"
#include <stdio.h>
#include "JniMain.h"
#include <string.h>
// 靜態方法 jclass
JNIEXPORT jstring JNICALL Java_com_bpj_ndk_JniMain_getStringFromC
(JNIEnv * env, jclass jclz) {
return (*env)->NewStringUTF(env, "C string");
}
// 非靜態方法 jobject
JNIEXPORT jstring JNICALL Java_com_bpj_ndk_JniMain_getStringFromC2
(JNIEnv * env, jobject jobj) {
return (*env)->NewStringUTF(env, "C string2");
}
6. 生成一個dll 動態庫
工具欄Debug->x86->配置管理器-平臺:x64
右鍵項目名->屬性->常規->項目默認值-> 配置類型->動態庫(.dll)
7. 在java中加載動態庫
拷貝dll文件到目錄下
- 觸發native函數
靜態庫和動態庫
都是函數庫。
靜態庫:.a
動態庫: .dll/.so
JNIEnv 是什麼?
C:
JNIEnv 結構體指針的別名
env 是二級指針
C++:
JNIEnv 是機構體的別名
env 是一級指針
每個native 函數,都至少有兩個參數(JNIEnv * , jclass/jobject)
jclass: native 靜態方法
jobject: native 非靜態方法