歡迎使用我的 在線工具

          小D

          讀歷史、看小說、寫程序都是我所愛。技術不好,頭腦不靈光,靠的是興趣。
          隨筆 - 35, 文章 - 25, 評論 - 13, 引用 - 0
          數據加載中……

          JNI學習記錄

          ?

          1.???? JNIJava與本地C/C++代碼相互操作的一種方案。

          2.???? 要使用JNI,需要:

          1),在Java源程序中使用native關鍵字聲明一個方法。

          ???????? 如:public native void callCppFunction();

          2),然后在命令行提示符下使用javah這個命令來生成關于JNI的本地頭文件。

          如:javah test.jni.MainArrayTest

          ???????? 3),在VC Studio中建立一個DLL工程,拷貝這個頭文件到該工程目錄下,拷貝

          ???????? %JAVA_HOME%"include下面的jni.hjni_md.h到工程目錄下,或者加到系統目下,具體需要拷貝的頭文件還要具體研究。

          4),建一個cpp源文件,實現生成的頭文件中聲明的函數。

          5),具體各種函數及數據類型的使用如下:具體自己研究:

          l?????? 簡單方法調用,基本數據類型的使用

          jclass clazz_TestNative = env->GetObjectClass(obj);

          /*??????

          jfieldID id_number = env->GetFieldID(clazz_TestNative,

          ?????????? "number", "I");

          jint number = env->GetIntField(obj, id_number);

          cout<<number<<endl;

          env->SetIntField(obj, id_number, 1000L);

          */

          //??????? jmethodID id_max = env->GetMethodID(clazz_TestNative, "max", "(DD)D");

          //??????? jdouble maxValue = env->CallDoubleMethod(obj, id_max, 3.14, 3.15);

          //??????? cout<<maxValue<<endl;

          jfieldID id_person = env->GetFieldID(clazz_TestNative, "person", "Ltest/jni/Father;");

          jobject person = env->GetObjectField(obj, id_person);

          jclass clazz_Father = env->FindClass("test/jni/Father");

          jmethodID id_Father_Function = env->GetMethodID(clazz_Father, "function", "()V");

          env->CallVoidMethod(person, id_Father_Function);

          env->CallNonvirtualObjectMethod(person,clazz_Father, id_Father_Function);

          l?????? 對象的使用

          jclass clazz_date = env->FindClass("java/util/Date");

          jmethodID outputDate_ID = env->GetMethodID(clazz_date, "<init>", "()V");

          jobject date_obj = env->NewObject(clazz_date, outputDate_ID);

          jmethodID mid_date_getTime = env->GetMethodID(clazz_date, "getTime", "()J");

          unsigned times = env->CallLongMethod(date_obj, mid_date_getTime);

          //??????? printf("%u",times);

          cout<<times<<endl;

          l?????? 字符串的簡單實用

          jfieldID fid_msg = env->GetFieldID(env->GetObjectClass(obj), "message", "Ljava/lang/String;");

          jstring j_msg = (jstring)env->GetObjectField(obj, fid_msg);

          //const jchar *p_jst = env->GetStringChars(j_msg, NULL);

          //MessageBoxW(NULL,(const wchar_t *)p_jst, L"Title", MB_OK);

          jint len = env->GetStringLength(j_msg);

          jchar *j_buf = new jchar[len+1];

          j_buf[len] = L'"0';

          env->GetStringRegion(j_msg, 0, len, j_buf);??????

          wstring wstr((const wchar_t *)j_buf);

          //env->ReleaseStringChars(j_msg, j_buf);//不能釋放字符數組啊

          delete []j_buf;

          std::reverse(wstr.begin(), wstr.end());

          jstring jnewStr = env->NewString((const jchar*)wstr.c_str(), wstr.size());

          env->SetObjectField(obj, fid_msg, jnewStr);

          ??????????????????

          l?????? 數組的使用

          jfieldID fid_arrays = env->GetFieldID(env->GetObjectClass(obj), "arrays", "[I");

          jintArray jint_arr = (jintArray)env->GetObjectField(obj, fid_arrays);

          jint *int_arr = env->GetIntArrayElements(jint_arr, NULL);

          jsize len = env->GetArrayLength(jint_arr);

          for(int i = 0; i < len; ++i)

          {

          //?????? cout<<int_arr[i]<<endl;

          }

          sort(int_arr, int_arr + len, less_second);

          env->ReleaseIntArrayElements(jint_arr, int_arr, /*JNI_ABORT/JNI_COMMIT/0*/0);

          }

          bool less_second(const int & m1, const int & m2)

          {

          ??????? return m1 > m2;

          }

          上面要注意在JNI中對Java中數據類型的映射,見頭文件的聲明。

          還有注意Java中關于對象類型的表示方法比如:int I, boolean Z,

          Object L<類的完整名稱,注意包名以/分隔>;,數組[<數據類型>

          如果不知道可以使用javap這個反編譯器。

          ????????

          ???????? 6)、更多資料,將Java手冊。

          ???????? 7)、編譯,生成DLL。將DLL的文件路徑加到Path環境變量下:

          ???????? 8)、在Main函數中加載動態庫。

          如:System.loadLibrary("TestNative4"),注意不要DLL擴展名,為了跨平臺嘛!

          9)、如果使用的是eclipse之類的IDE工具,請重啟,因為該類工具在啟動時,默認讀取了系統變量,但是不會監視變量的變化。

          10)、注意在JNI中對Java對象的引用。不然垃圾回收將會產生問題。注意全局引用,局部引用、弱全局引用的使用。

          ?????????? 局部引用,也就是本地方法中返回引用。應該使用DeleteLocalRef釋放該引用。NewLocalRef創建。還用很多方式創建。

          ?????????? 全局引用,需要手動釋放,防止垃圾回收器回收。需要使用NewGlobalRef函數創建,釋放它需要使用DeleteGlobalRef函數。

          ?????????? 弱全局引用,需要編程人員手動釋放,但是它不防止垃圾回收器的回收。

          ?????????? 使用NewWeakGlobalRef創建,使用DeleteWeakGlobalref釋放。IsSamObject(jobject obj1, jobject obj2)判斷弱全局引用指向的對象是否已被回收。

          posted on 2009-11-04 18:44 vagasnail 閱讀(6432) 評論(0)  編輯  收藏 所屬分類: JavaEE


          只有注冊用戶登錄后才能發表評論。


          網站導航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           
          主站蜘蛛池模板: 株洲县| 贡山| 安图县| 城市| 札达县| 鲁山县| 留坝县| 盐城市| 余江县| 东乡县| 武定县| 万源市| 洛川县| 青神县| 江北区| 拉萨市| 呼和浩特市| 桐梓县| 襄樊市| 信丰县| 旅游| 康定县| 泰兴市| 阿克苏市| 宜兰市| 罗田县| 霞浦县| 麦盖提县| 无为县| 红桥区| 监利县| 乳源| 沭阳县| 南阳市| 武威市| 克拉玛依市| 宜春市| 新宁县| 望城县| 横峰县| 石台县|