Java JNI简单实现
生活随笔
收集整理的這篇文章主要介紹了
Java JNI简单实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Java JNI簡單實現 JNI(Java Native Interface)允許了Java和C&C++進行交互?這不折騰人嘛! 一、JNI簡述 http://baike.baidu.com/view/1272329.htm,真心懶了-_-! 二、JNI基本類型 copy表一份,很詳細的了!
表2 Java類型映射 三、Java調用C&C++ 1)Java類中編寫native聲明的方法。 2)javah命令生成JNI樣式.h文件。 貌似我一直是直接建一個.h,然后copy之前的改改完事。需要注意以下幾點:1、JNI調用函數必須要用C編譯器編譯。也就是C++別忘了extern "C"那塊;2、方法名格式:Java_pacakege_class_method。 例子程序的HelloJni.h文件: #ifndef?HELLOJNI_H_? #define?HELLOJNI_H_? ? #include?<jni.h>? ? //?JNI調用函數必須要用C編譯器編譯? //?C++不加extern?"C",調用會有異常? #ifdef?__cplusplus? extern?"C"?{? #endif? ? /*? ?*?1、JNIEXPORT、JNICALL:jni的宏? ?*?2、jstring:返回值類型(對應java的string)? ?*?3、C方法名:Java_pacakege_class_method? ?*?4、JNIEnv*、jobject:jni必要參數(jni環境、java對象)? ?*/? JNIEXPORT?void?JNICALL?Java_org_join_jni_JniTest_sayHelloWin?(JNIEnv*,?jobject,?int,?int,?int,?int);? ? #ifdef?__cplusplus? }? #endif? ? #endif?/*?HELLOJNI_H_?*/? 3)用C&C++方法實現本地方法,編譯成動態庫 4)Java類中用System.loadLibrary()或System.load()方法加載生成的dll文件 System.loadLibrary():裝載Windows\System32下或jre\bin或Tomcat\bin目錄下的本地鏈接庫 System.load():根據具體的目錄來加截本地鏈接庫,必須是絕對路徑 5)OK! 注意jni方法的使用,C&C++格式是不一樣的,如下: C 格式:(*env) -> <jni function> (env, <parameters>) /**?C回調Java方法(靜態)?*/? public?static?int?add(int?x,?int?y)?{? System.out.println("==Java靜態add方法==");? return?x?+?y;? }? ? /**?C回調Java方法(非靜態)?*/? public?int?sub(int?x,?int?y)?{? System.out.println("==Java非靜態sub方法==");? return?x?-?y;? }? 2)CallJava.h #ifndef?CALLJAVA_H_? #define?CALLJAVA_H_? ? #include?<jni.h>? #include?<stdio.h>? #include?<stdlib.h>? ? int?add(JNIEnv*,?int,?int);? int?sub(JNIEnv*,?int,?int);? ? jobject?getInstance(JNIEnv*,?jclass);? ? #endif?/*?CALLJAVA_H_?*/? 3)CallJava.cpp #include?"CallJava.h"? ? /**? ?*?C回調Java方法(靜態)? ?*/? int?add(JNIEnv?*env,?int?x,?int?y)?{? ????//?獲取類? ????jclass?AnalyzeCidUtil?=?env->FindClass("org/join/jni/JniTest");? ????if?(NULL?==?AnalyzeCidUtil)?{? ????????return?-1;? ????}? ? ????//?獲取類add靜態方法? ????/*? ?????*?第三個參數為方法簽名? ?????*? ?????*?可用JDK自帶工具javap生成該類所有方法簽名? ?????*?控制臺進入該類class文件目錄,輸入:javap?-s?-private?類名? ?????*/? ????jmethodID?add?=?env->GetStaticMethodID(AnalyzeCidUtil,?"add",?"(II)I");? ????if?(NULL?==?sub)?{? ????????env->DeleteLocalRef(AnalyzeCidUtil);?//?刪除類指引? ????????return?-2;? ????}? ? ????//?調用靜態int方法? ????int?result?=?env->CallStaticIntMethod(AnalyzeCidUtil,?add,?x,?y);? ? ????//?返回結果? ????return?result;? }? ? /**? ?*?C回調Java方法(非靜態)? ?*/? int?sub(JNIEnv?*env,?int?x,?int?y)?{? ????//?獲取類? ????jclass?AnalyzeCidUtil?=?env->FindClass("org/join/jni/JniTest");? ????if?(NULL?==?AnalyzeCidUtil)?{? ????????return?-1;? ????}? ? ????//?實例化類對象? ????jobject?mAnalyzeCidUtil?=?getInstance(env,?AnalyzeCidUtil);? ????if?(NULL?==?mAnalyzeCidUtil)?{? ????????env->DeleteLocalRef(AnalyzeCidUtil);?//?刪除類指引? ????????return?-2;? ????}? ? ????//?獲取對象sub方法? ????jmethodID?sub?=?env->GetMethodID(AnalyzeCidUtil,?"sub",?"(II)I");? ????if?(NULL?==?sub)?{? ????????env->DeleteLocalRef(AnalyzeCidUtil);?//?刪除類指引? ????????env->DeleteLocalRef(mAnalyzeCidUtil);?//?刪除類對象指引? ????????return?-3;? ????}? ? ????//?調用非靜態int方法? ????int?result?=?env->CallIntMethod(mAnalyzeCidUtil,?sub,?x,?y);? ? ????//?返回結果? ????return?result;? }? ? /**? ?*?實例化類對象? ?*/? jobject?getInstance(JNIEnv?*env,?jclass?clazz)?{? ????//?獲取構造方法? ????jmethodID?constructor?=?env->GetMethodID(clazz,?"<init>",?"()V");? ????if?(NULL?==?constructor)?{? ????????return?NULL;? ????}? ????//?實例化類對象? ????return?env->NewObject(clazz,?constructor);? }? 注意靜態和非靜態方法相差的實例化類對象的區別! 五、后記 附件樣例工程有兩個,JavaJni是Java工程,JniDll_win32是VS2010工程。 Java工程帶了在我環境下編譯的dll,可直接跑,但我相信大多數人都跑不通-_-!(在朋友電腦上曾試過,可能是Java不同版本的原因吧)
| Java類型 | 本地類型 | 描述 |
| boolean | jboolean | C/C++8位整型 |
| byte | jbyte | C/C++帶符號的8位整型 |
| char | jchar | C/C++無符號的16位整型 |
| short | jshort | C/C++帶符號的16位整型 |
| int | jint | C/C++帶符號的32位整型 |
| long | jlong | C/C++帶符號的64位整型 |
| float | jfloat | C/C++32位浮點型 |
| double | jdouble | C/C++64位浮點型 |
| Object | jobject | 任何Java對象,或者沒有對應java類型的對象 |
| Class | jclass | Class對象 |
| String | jstring | 字符串對象 |
| Object[] | jobjectArray | 任何對象的數組 |
| boolean[] | jbooleanArray | 布爾型數組 |
| byte[] | jbyteArray | 比特型數組 |
| char[] | jcharArray | 字符型數組 |
| short[] | jshortArray | 短整型數組 |
| int[] | jintArray | 整型數組 |
| long[] | jlongArray | 長整型數組 |
| float[] | jfloatArray | 浮點型數組 |
| double[] | jdoubleArray | 雙浮點型數組 |
? ? ? ? ? ? ? ? ??返回jstring:return (*env)->NewStringUTF(env, "XXX");
C++ 格式:env -> <jni function> (<parameters>) 返回jstring:return env->NewStringUTF("XXX"); 另外數組類型的話,jni提供了操作的函數,稍復雜點,例子里沒寫也就不說了。 四、C&C++回調Java 直接看代碼吧,每步都有注釋了。 1)包org.join.jni下類JniTest內定義的兩方法? ? ? ? ?總之不行或者非win32系統的話重新編譯吧,源文件在JniDll_win32工程內都有。注意include Java安裝目錄下include文件夾內的頭文件哦。VS2010的話,右鍵工程 -> Properties -> Configuration Properties -> C/C++ -> General -> Additional Include Directories內設置,如:%JAVA_HOME%\include;%JAVA_HOME%\include\win32。
??
附件:http://down.51cto.com/data/2359729
? ? ?本文轉自winorlose2000 51CTO博客,原文鏈接:http://blog.51cto.com/vaero/770139,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的Java JNI简单实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: laravel中单独获取一个错误信息的方
- 下一篇: Eclipse中最常用的热键