android windows 上JNI編程,androidjni

來源:互聯網
上載者:User

android windows 上JNI編程,androidjni
昨天學習windows上的JNI編程,JNI說白了就是java和c語言的一個互相溝通的橋樑,java可以調用JNI來完成調用C語言實現的方法。JNI的全稱是(Java native interface),其實在編程重你只需要將與java互動的函數寫出來,其他的C語言內部調用的就可以直接使用C語言相關文法了。閑話少說,開始正題吧。要想在windroid或者是linux上使用JNI必須要下載NDK的並且指定路徑,在windows我們還需要安裝一個sygwin,這裡我就不再說怎樣安裝cygwin了,在你安裝好的cygwin檔案夾中找到一個etc的檔案夾,在這個檔案中找到一個profile檔案,修改其中的Path後加上:(ndk的路徑),在我理解ndk就是構建出了一個重pc到android的一個交叉編譯環境,當然它裡面還有很多我不知道的,還有待探索。然後我們就可以開始使用了,當然你要是用eclipse寫C/C++還需要安裝cdt外掛程式。安裝過後就可以使用eclipse編寫c/c++的代碼了。下面我們來看看代碼怎樣編寫吧,首先我們在android工程中建立一個jni的檔案夾,在jni的檔案夾中建立c語言的源檔案,在android中穿件一個類,類中可以使用native標識建立函數例如下面:public class DataProvider {  //帶參數的c語言調用java語言 public int add2( int x, int y){  return x + y; }  //無參數的函數C語言調用java語言 public void show(){  System.out.println( "我被調用了啊" ); }  //無參數的靜態函數C語言調用java語言 public static void show2(){  System.out.println( "我又被調用了啊" ); } //將函數使用native標識,可以自動產生相應的函數 public native int add(int x, int y); public native int sayHello( String hello ); public native int[] array(int[] arr);  public native int callbackadd2(); public native void callbackshow(); public native static void callbackshow2(); public native void callbackshow3();}
將這個類寫好了就可以使用javah (類的全類名), 全類名是指包名+類名,例如com.example.testjni.DataProvider,這樣就可以產生一個c語言中使用的標頭檔例如:/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_example_testjni_DataProvider */#ifndef _Included_com_example_testjni_DataProvider#define _Included_com_example_testjni_DataProvider#ifdef __cplusplusextern "C" {#endif/* * Class:     com_example_testjni_DataProvider * Method:    add * Signature: (II)I */JNIEXPORT jint JNICALL Java_com_example_testjni_DataProvider_add  (JNIEnv *, jobject, jint, jint);/* * Class:     com_example_testjni_DataProvider * Method:    sayHello * Signature: (Ljava/lang/String;)I */JNIEXPORT jint JNICALL Java_com_example_testjni_DataProvider_sayHello  (JNIEnv *, jobject, jstring);/* * Class:     com_example_testjni_DataProvider * Method:    array * Signature: ([I)[I */JNIEXPORT jintArray JNICALL Java_com_example_testjni_DataProvider_array  (JNIEnv *, jobject, jintArray);/* * Class:     com_example_testjni_DataProvider * Method:    callbackadd2 * Signature: ()I */JNIEXPORT jint JNICALL Java_com_example_testjni_DataProvider_callbackadd2  (JNIEnv *, jobject);/* * Class:     com_example_testjni_DataProvider * Method:    callbackshow * Signature: ()V */JNIEXPORT void JNICALL Java_com_example_testjni_DataProvider_callbackshow  (JNIEnv *, jobject);/* * Class:     com_example_testjni_DataProvider * Method:    callbackshow2 * Signature: ()V */JNIEXPORT void JNICALL Java_com_example_testjni_DataProvider_callbackshow2  (JNIEnv *env, jclass);/* * Class:     com_example_testjni_DataProvider * Method:    callbackshow3 * Signature: ()V */JNIEXPORT void JNICALL Java_com_example_testjni_DataProvider_callbackshow3  (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif這些都是使用javah後自動產生的。下一步我將該在c語言中是實現這些函數了,在此之前還需要建立一個mk檔案,這個檔案就是makefile,C語言在編譯成庫的情況下就可以讀取makefile來編譯。mk檔案:   LOCAL_PATH := $(call my-dir)   include $(CLEAR_VARS)      #對應的c語言的函數庫   LOCAL_MODULE    := hello      #對應c代碼的檔案   LOCAL_SRC_FILES := hello.c functions.c      LOCAL_LDLIBS := -llog//使用本地庫   include $(BUILD_SHARED_LIBRARY)

#include <stdio.h>#include "com_example_testjni_DataProvider.h" //引用標頭檔#include <android/log.h> //列印的日誌const char *TAG = "clog";#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__ );#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__ );//使用log標頭檔中的函數列印日誌到eclipse中的logcat,在這裡需要在mk檔案中添加庫引用,LOCAL_LDLIBS += -llogJNIEXPORT jint JNICALL Java_com_example_testjni_DataProvider_add  (JNIEnv *env, jobject o, jint x, jint y){ LOGI("%d\n", x ); LOGD("%d\n", y ); return x + y; //直接返回就可以}//int print(jintArray localarray, int i);int print( int* localarray, int i ){ LOGD( "array = %d\n", *(localarray+i)); return 0;}//平常的c語言代碼,可以直接調用/* * Class:     com_example_testjni_DataProvider * Method:    sayHello * Signature: (Ljava/lang/String;)I */JNIEXPORT jint JNICALL Java_com_example_testjni_DataProvider_sayHello  (JNIEnv *env, jobject o, jstring hello){}/* * Class:     com_example_testjni_DataProvider * Method:    array * Signature: ([I)[I */JNIEXPORT jintArray JNICALL Java_com_example_testjni_DataProvider_array  (JNIEnv *env, jobject obj, jintArray array )//傳的是一個java中int型數組,java調用c語言{ //獲得數組長度 int length = (*env)->GetArrayLength(env, array); int i; jint* localarray = (*env)->GetIntArrayElements(env, array, 0); for( i = 0; i < length; i++ ){  *(localarray+i) += 5;  print( localarray, i ); } return array;}/* * Class:     com_example_testjni_DataProvider * Method:    callbackadd2 * Signature: ()I */JNIEXPORT jint JNICALL Java_com_example_testjni_DataProvider_callbackadd2  (JNIEnv *env, jobject obj){ jclass clazz = (*env)->FindClass(env, "com/example/testjni/DataProvider"); jmethodID mid = (*env)->GetMethodID(env, clazz, "add2", "(II)I"); return (*env)->CallIntMethod(env, obj, mid, 3, 5);}/* * Class:     com_example_testjni_DataProvider * Method:    callbackshow * Signature: ()V */JNIEXPORT void JNICALL Java_com_example_testjni_DataProvider_callbackshow  (JNIEnv *env, jobject obj){ jclass clazz = (*env)->FindClass(env, "com/example/testjni/DataProvider"); jmethodID mid = (*env)->GetMethodID(env, clazz, "show", "()V");// (*env)->CallVoidMethod(env, obj, mid);}/* * Class:     com_example_testjni_DataProvider * Method:    callbackshow2 * Signature: ()V */JNIEXPORT void JNICALL Java_com_example_testjni_DataProvider_callbackshow2  (JNIEnv *env, jclass jc){ jmethodID mid = (*env)->GetStaticMethodID(env, jc, "show2", "()V"); jobject obj =  (*env)->CallStaticObjectMethod(env, jc, mid); (*env)->CallVoidMethod(env, obj, mid);}/* * Class:     com_example_testjni_DataProvider * Method:    callbackshow3 * Signature: ()V */JNIEXPORT void JNICALL Java_com_example_testjni_DataProvider_callbackshow3  (JNIEnv *env, jobject obj){ jclass clazz = (*env)->FindClass(env, "com/example/testjni/DataProvider"); jmethodID mid = (*env)->GetStaticMethodID(env, clazz, "show2", "()V"); (*env)->CallVoidMethod(env, obj, mid);}java調用C語言將java傳過來的值,使用jni的方法進行處理,然後使用,返回,c語言調用java需要在C語言代碼中進行映射,例如:JNIEXPORT void JNICALL Java_com_example_testjni_DataProvider_callbackshow3  (JNIEnv *env, jobject obj){ jclass clazz = (*env)->FindClass(env, "com/example/testjni/DataProvider");//得到類的位元組碼 jmethodID mid = (*env)->GetStaticMethodID(env, clazz, "show2", "()V");//得到函數的id (*env)->CallVoidMethod(env, obj, mid);//執行函數}執行函數有不同的call函數,例如返回值是int是CallIntMethod(env, obj, mid, 3, 5);空類型是CallVoidMethod(env, obj, mid);後面的()V是函數簽名,代表是返回值是void型,無參的函數。(II)I返回值是int型參數是兩個int值得函數。c語言編寫後要在工程的src目錄下運行ndk-bulid命令就可以產生一個c語言庫,在eclipse工程目錄中也有顯示。在每次編譯之前需要刪除obj檔案夾,以清除緩衝。jni對於一些可以很大的提高java代碼的隱秘性,而且使用c語言開發jni程式可以提高效率。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.