本社群由Nantou.py使用者社群以及國立虎尾科技大學電機資訊學院負責維護,它是一群熱愛智慧生活科技以及Python的專業教師所組成,大家一同快樂地研究有關數位生活中人工智慧、大數據、物聯網、雲端服務、APPS、福祉科技、感知網路服務、車載網路服務、及網際網路等資通訊技術,並運用這些資通訊以及Python技術來提升我們的日常生活品質,建立更好的生活環境。
2012年4月19日 星期四
Java Native Interface (JNI) Android C呼叫Java (底層呼叫上層)間傳遞篇--以靜態或動態類型為例
在"Java Native Interface (JNI)入門 -- 觀念篇"這篇文章中實作二C呼叫JAVA部份說明當 C 呼叫 Java 需要建立一個 JVM 通道,然後透過Get----MethodID 搭配 Call----MethodID獲取JAVA中的指定參數。
本篇學習重點在於如何在Android NDK中由C呼叫Java。
C呼叫Java會遇到的機會通常在於Java程式比C好寫清況或是將舊有C程式的移植時發生。
執行情況大致下列兩種:
1.Java 進入C後,C再回到Java 呼叫函數。
2.Java 進入C; C產生thread然後由這個thread回到Java 呼叫函數。
一般來說完成上述功能,會透過Get----MethodID搭配Call----Method方法來完成,
其中Get----MethodID 中 --- 表示的是對應(Mapping)方法的靜態(Static)或動態(non-Static)類型。
而 CallStatic<Type>Method或Call <Type> Method 中 <Type> 表示的是呼叫(Call)方法的返回值 ,例如:Int、Char、Void、Object、...等。
例如:
呼叫 JAVA 靜態類型:
(*jniEnv)->GetStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig); <-- C Mapping
(*jniEnv)->CallStatic <Type> Method(JNIEnv *env, jclass clazz, jmethodID methodID, ...); <-- C call Java
呼叫 JAVA 動態類型:
(*jniEnv)->GetMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig); <-- C Mapping
(*jniEnv)->Call <Type> Method(JNIEnv *env, jobject obj, jmethodID methodID, ...); <-- C call Java
至於詳細的對應(Mapping)與呼叫(Call)方法,三言兩語不太可能講完的,詳細資訊可在網路上搜尋 "The Java Native Interface Programmer’s Guide and Specification" 的一個 PDF檔案內容中有更詳細的說明(查文件最後的Index)。
實作一、靜態呼叫
程式碼:
JAVA:
C:
結果:
實作二、動態呼叫
程式碼:
Java:
C:
結果:
參考:
1.The Java Native Interface Programmer’s Guide and Specification
http://java.sun.com/docs/books/jni/
2.給新手 - static 成員
http://www.javaworld.com.tw/jute/post/view?bid=29&id=11490&sty=1&tpg=1&age=-1
===========延伸閱讀========================================
第一支Android NDK程式--HelloJni
Java Native Interface (JNI) 的使用時機及影響
Java Native Interface (JNI)入門 -- 觀念篇
Java Native Interface (JNI) 實戰篇
Java Native Interface (JNI) Android實戰篇(使用NDK) -- HelloUart
Java Native Interface (JNI) Android算數篇(使用NDK) -- Fibonacci Sequence
Java Native Interface (JNI) Android C++語言篇--以Hello-JNI為例
Java Native Interface (JNI) Android C++語言篇--以Hello-JNI為例
Java Native Interface (JNI) Android C程式間傳遞篇--以two-libs為例
Java Native Interface (JNI) Android C呼叫Java (底層呼叫上層)間傳遞篇--以靜態或動態類型為例
Android NDK Beginner’s Guide
訂閱:
張貼留言 (Atom)
你好 我用hellojni來修改成實作1 , 在跑模擬時出現Unfortunately,HelloJni has stopped ,程式碼部份都如上修改,唯一可能會不同的地方剩xml檔,我是只有留一個Button用的部份,請問蚊子大有辦法幫我解惑一下嗎??還是說jni不行這樣直接修改?
回覆刪除初學jni還不是很了解,麻煩您了,感謝您!!
您先看一下Logcat錯誤訊息,我的經驗很多都是void後面的參數沒有按照Android規範來寫:
刪除Java_Android Package Name_類名稱_native函數名,並注意底線及大小寫
如果不知道怎麼寫才對,很多人都是產生出*.h檔來看內容,部落格有一篇你可以參考看看如何產生h檔
http://cheng-min-i-taiwan.blogspot.tw/2012/08/javah-jni-c-h.html
感謝你~~我果然有些大小寫寫錯了。
回覆刪除在修改了之後剩下__android_log_print會無法辨識的問題,解決辦法是在android.mk檔裡的include $(CLEAR_VARS)下行增加LOCAL_LDLIBS := -lm -llog再儲存就可以了,希望能幫助到^^
感謝您提供的資訊^^
刪除