<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                接續上篇[JNI開發系列③C語言調用Java字段與方法](http://www.jianshu.com/p/9cc6e3f0ead7) ###前情提要 Java調用C方法很簡單 , 只需要編寫`native`方法即可 , 通過C去調用Java的字段與方法 , 則需要比較復雜的操作 , 上篇中介紹了 , C調用的Java字段與方法的幾個套路: > 步驟一 、 得到jclass, 字節碼對象 , 如果是static native修飾 , 則函數會以jclass類型傳入 , 非靜態則需要得到jclass類型 。 >步驟二 、得到字段或方法ID , 區分靜態字段與對象字段 , 靜態字段或方法調用(*env)->GetStaticFieldID,(*env)->GetMethodID函數得到ID , 對象字段調用(*env)->GetFieldID,(*env)->GetStaticMethodID得到ID 。 可以得到一個套路 , 靜態修飾的 , 則調用static標識的函數 , 非靜態的則調用常規函數 。 > 步驟三 、 取得字段的值或調用方法 , 需要注意的是, 得到字段的值與調用方法 , 都有類型的區分 。引用類型則使用GetObjectField,?CallStaticObjectMethod, 其他類型 , 則有對于的jxxx類型對應 。套路簡寫:Get<Type>Field,?GetStatic<Type>Field,?Call<Type>Method,?CallStatic<Type>Method?。 > 步驟四 、 類型轉換 , 如果是Java引用類型 , 則需要進行類型轉換 ### C 調用Java對象的構造方法 > C調用Java的構造方法與調用普通方法略有不同 , 其不同之處在于方法名稱上 , 普通方法直接使用`方法名` , 構造方法則不是使用類名 , 而使用一個固定寫法`<init>` 。 ```java java code 使用C語言創建一個Date對象,獲取時間戳 private native long accessConstructorMethod() ; public static void main(String[] args) { long timeLong = jni.accessConstructorMethod() ; SimpleDateFormat sdf = new SimpleDateFormat(); sdf.applyPattern("yyyy-MM-dd HH:mm:ss") ; String dateString = sdf.format(new Date(timeLong)) ; } ``` > 使用C創建Java對象 , 并調用方法 ```c /*訪問java對象的構造方法*/ JNIEXPORT jlong JNICALL Java_com_zeno_jni_HelloJni_accessConstructorMethod (JNIEnv *env, jobject jobj) { // 找到Date的jclass jclass dateCls = (*env)->FindClass(env, "java/util/Date"); // 得到構造方法id jmethodID dateConstructMid = (*env)->GetMethodID(env, dateCls, "<init>", "()V"); // 創建Date對象 jobject dateObj = (*env)->NewObject(env, dateCls, dateConstructMid); // 得到getTime方法ID jmethodID getTimeMid = (*env)->GetMethodID(env, dateCls, "getTime", "()J"); // 調用getTime方法 jlong timeLong = (*env)->CallLongMethod(env, dateObj, getTimeMid); printf("new Date().getTime : %lld\n", timeLong); return timeLong; } ``` _Tips:_ C實例化Java對象的時候 , 首先需要找到對象的class , 以全類名表示 , `.`用`/`代替 (`java.util.Date --> Java/util/Date`)。Java的構造函數名稱為固定的`<init>`名稱 , 通過`NewObject()`函數來創建Java對象 。需要注意的是簽名 , 我們可以通過`javap -s -p`來獲取簽名 。常見簽名如下: |數據類型|簽名| |:---:|:---:| |boolean|Z| |byte|B| |char|C| |short|S| |int|I| |long|L| |float|F| |double|D| |void|V| |object|L開頭,然后以/分隔的完整類型,后面再加`;`例如:String類型簽名 `Ljava/lang/String`| |Array|以[開頭,再加上數組元素的簽名。例如int[]的簽名是 [I , int[][]是[[I| ### C與Java的字符轉換 在開發中 , 我們常常都會遇到字符編碼問題 , web開發的時候 , 時常需要指定網頁的編碼 , 國內一般常用GBK與UTF-8 ,這兩種編碼格式 。 我們在開發項目的時候 , 也會指定項目的文件編碼 , 因為不同文件編碼對于漢字的支持與處理不同 , GBK采用的是一字節和雙字節編碼 , 而UTF-8則采用的是 , 一至四個字節編碼 , 單個字符使用一個直接表示 , 漢字則使用四個字節表示 。 ```java java code private native String cTransformChar(String str) ; public static void main(String[] args) { HelloJNI jni = new HelloJNI() ; System.out.println(jni.cTransformChar("住")); } ``` > C處理字符編碼 ```c /*C的字符轉換*/ JNIEXPORT jstring JNICALL Java_com_zeno_jni_HelloJNI_cTransformChar (JNIEnv *env, jobject jobj,jstring jStr) { // 將jstring轉換成c字符指針 char *cStr = (*env)->GetStringUTFChars(env, jStr, NULL); jsize js = (*env)->GetStringLength(env, jStr); printf("傳進來的值size : %d\n", js); printf("傳進來的值 : %s\n", cStr); char destBuffer[50] = "非我 and 小九"; // 得到String類 jclass stringCls = (*env)->FindClass(env, "java/lang/String"); // 得到構造方法的ID jmethodID stringConstructMid = (*env)->GetMethodID(env, stringCls, "<init>", "([BLjava/lang/String;)V"); /* 使用到的Java構造方法 String(byte[] bytes, String charsetName) 通過使用指定的 charset 解碼指定的 byte 數組,構造一個新的 String。 */ // 構建一個bytes數組 jbyteArray strBytes = (*env)->NewByteArray(env, 50); // 設置字符數組 (*env)->SetByteArrayRegion(env, strBytes, 0, strlen(destBuffer), destBuffer); // 構建字符編碼 jstring charSetName = (*env)->NewStringUTF(env, "GBK"); // 創建String類的對象 jstring transformStr = (*env)->NewObject(env, stringCls, stringConstructMid, strBytes, charSetName); return transformStr; } ``` _Tips_ 如果是使用的eclipse控制臺輸出 , 一定要注意控制臺的字符編碼 , 如果編碼不統一 , 控制臺就會輸出亂碼 ,如:如果要輸出的字符是UTF-8而控制臺是GB2312 , 則會輸出亂碼 。 如果出現亂碼 , 可以將字符寫入到文件中 , 看看是否會亂碼 ,如果亂碼 ,可以使用notepad++看一下文件的編碼 , 如果編碼一致 , 則會顯示正常 。 ### 結語 這幾天公司產品上線 , 有點忙碌 , 沒多少時間寫文章 , 今天恢復寫文章的進度。昨天和一個創業公司的CEO聊了聊 , 發現自己欠缺的東西還有很多很多 , 對于產品的架構 , 如何從0到1 , 將想法轉換為產品 , 沒有一個完整的產品思路 ,也沒有產品經理的思維能力,有的只是對界面的吹毛求疵 , 對部分功能的自以為是 。任何行業 , 沒有深入進去 , 看的永遠只是表面 , 都是別人玩剩下的 。 ### 刻意練習技術 , 時刻思考產品 。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看