Java Native Interface(JNI)
JNI 是用來讓Java跟別種語言溝通的函式庫
Android中是讓Java及C之間溝通
分為Java Call C及C Call Java
Android Native Development Tools(NDK)
將C code包成.so檔,供Java利用
流程方法
藉由java撰寫native method,JNI即可在Java中呼叫C寫的程式
C的程式藉由NDK包成.so檔,就可以被JNI呼叫
//=============================================================
程式流程
1). (java) 撰寫native method,不需實做
2). 將寫好的.java檔,編成.class檔,再轉成.h檔
3). (C) 撰寫C程式碼,實做.h中的function標頭
3). 利用NDK將C程式碼轉成.so檔
4). (java) 利用JNI呼叫C的程式
//=============================================================
步驟
1). (java) 撰寫native method,不需實做
native method前要加native
要load的.so檔是libcal_bmi_c.so,扣除掉前面的lib及後面的.so
method是calbmi,回傳是double的型態
從Java傳入使用者輸入的height, weight
[Bmi.java]
package com.jni; public class Bmi { public native double calbmi(double height, double weight); static{ //要load的.so檔。去掉開頭的lib,及結尾的.so System.loadLibrary("cal_bmi_c"); } }2). 將寫好的.java檔,編成.class檔,再轉成.h檔
Eclipse會自動編成.class檔
進入project的資料夾,新開jni資料夾
將編好的.h檔放在jni資料夾中
$ cd [project資料夾] $ mkdir jni $ cd jni $ javah -jni -classpath [放置class的資料夾] [package].[class] ex: javah -jni -classpath /home/qn_lo/develop/android/workspace/BmiJni/bin/classes com.jni.Bmi
3). (C) 撰寫C程式碼,實做.h中的function標頭在jni資料夾新增C程式碼檔案
將.h檔的JNIEXPORT複製到C並實作
[com_jni_Bmi.h]
/* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class com_jni_Bmi */ #ifndef _Included_com_jni_Bmi #define _Included_com_jni_Bmi #ifdef __cplusplus extern "C" { #endif /* * Class: com_jni_Bmi * Method: calbmi * Signature: (DD)D */ JNIEXPORT jdouble JNICALL Java_com_jni_Bmi_calbmi (JNIEnv *, jobject, jdouble, jdouble); #ifdef __cplusplus } #endif #endif
[com_jni_Bmi.c]
#include #include JNIEXPORT jdouble JNICALL Java_com_jni_Bmi_calbmi (JNIEnv *env, jobject obj, jdouble cheight, jdouble cweight) { double height,weight,bmi; height=cheight/100; weight=cweight; bmi=weight/(height*height); return bmi; }
4). 撰寫NDK需要的Android.mk在jni資料夾中新增Android.mk
LOCAL_MODULE是編成的.so檔名
LOCAL_SRC_FILES是要編的C程式碼檔名
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := cal_bmi_c LOCAL_SRC_FILES := com_jni_Bmi.c include $(BUILD_SHARED_LIBRARY)
5). 利用NDK將C程式碼轉成.so檔
a). 先到Android NDK下載NDK
b). 在project資料夾下新建libs的資料夾
如果有需要,可在Eclipse中在Project按右鍵reflesh
c). 在Eclipse的Project點右鍵[properties]
在[Builders]中new一個編譯器,選擇program
輸入Builder的Name,在Main標籤中,輸入Location及Working Directory
在Refresh標籤中,將Refresh resource upon completion勾選
並選擇Specific resource的路徑為project的libs
在Build Options標籤中
勾選Specify working set of relevant resource
並選擇Specify Resource路徑為Project的jni
d). 按下Build All的按鈕將C編成.so檔
6). (java) 利用JNI呼叫C的程式在java要呼叫,[放JNI的class]().[native method]
new Bmi().calbmi(height, weight)
參考資料:
http://ironurbane.iteye.com/blog/425513
http://kitty.2y.idv.tw/~enijmax/linux/CLib_Jni.html
沒有留言:
張貼留言