JNI的全稱是java native interface,用來調用某些特定於系統平臺或者硬件的操做,可是它只能調用c/c++的代碼,如果其它語言代碼,只能經過c/c++進行二次調用。
關於JNI的完整技術文檔,你們能夠查看下面這個網址:
下面咱們看下JNI如何執行回調函數:
咱們知道在c/c++回調函數能夠經過函數指針執行,可是在Java中已經沒有指針的概念,在這裏,咱們先傳遞一個類對象給native函數,而後再dll中調用指望的函數便可。
下面的這個例子中,咱們經過回調傳遞一個字符串給java,這在java和c/c++混合編程時傳遞dll內部的出錯或其餘信息到java層是頗有用的。
1. 首先建立一個java類文件,封裝一個native函數和一個用於回調的函數
- package jni;
- public class Log{
- static{
- System.loadLibrary("mylib");
- }
-
- //用來回調,輸出c代碼層的信息
- public void output(String out){
- System.out.println(out);
- }
-
- //native函數,用來傳遞對象
- public native void test(Log log);
-
- public static void main(String[] args){
- Log log = new Log();
-
- log.test(log);
- }
- }
2. 調用javah命令,生成對應的c/c++都文件
- /* DO NOT EDIT THIS FILE - it is machine generated */
- #include <jni.h>
- /* Header for class jni_Log */
- #ifndef _Included_jni_Log
- #define _Included_jni_Log
- #ifdef __cplusplus
- extern "C" {
- #endif
- /*
- * Class: jni_Log
- * Method: test
- * Signature: (Ljni/Log;)V
- */
- JNIEXPORT void JNICALL Java_jni_Log_test
- (JNIEnv *, jobject, jobject);
- #ifdef __cplusplus
- }
- #endif
- #endif
3. 利用vc和生成的頭文件完成一個dll
- #include <windows.h>
- #include "jni_Log.h"
- int WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReasion,PVOID pvReserved)
- {
- return TRUE;
- }
- JNIEXPORT void JNICALL Java_jni_Log_test(JNIEnv * env, jobject obj, jobject log)
- {
- jclass cls = (*env)->GetObjectClass(env, log);
- jmethodID jmid = (*env)->GetMethodID(env, cls, "output", "(Ljava/lang/String;)V");
- jstring info = (*env)->NewStringUTF(env, "i am a error!");
- (*env)->CallVoidMethod(env,log, jmid,info);
- (*env)->ReleaseStringUTFChars(env,info,(*env)->GetStringUTFChars(env, info, FALSE));
- }
編譯完成後,將mylib.dll放到與jni同級的目錄中,運行命令java jni.Log,便可看到控制檯成功打印信息css
"i am a error!"。java