【詳解】JNI (Java Native Interface) (三)

貓毛·波拿巴發表於2018-10-26

案例三:C程式碼訪問Java物件的例項變數

    獲取物件的例項變數的步驟:

  1. 通過GetObjectClass()方法獲得此物件的類引用

  2. 通過類引用的GetFieldID()方法獲得例項變數的Field ID.

    你需要提供 變數名欄位型別描述符

    • 對於Java 類, 欄位描述符格式為 "L<類全稱>;" 類全稱中,點"."用 "/"代替。例如,String 的描述符為"Ljava/lang/String;"

      注意:這裡不要漏了分號";"

    • 對於基本型別,則有固定標識。注:這裡不需要分號。

      int =>  "I" ,byte => "B",short => "S",long => "J",float => "F",double => "D",char => "C",boolean => "Z"

    • 對於陣列,則結合以上型別描述符,加上字首"[",

      如Object陣列,用"[L/java/lang/Object;"表示

      int陣列,用"[I"表示

   3. 基於FieldID,通過GetObjectField()方法或Get<基本型別>Field()方法獲取例項變數。

   4. 如果需要更新例項變數,可以使用SetObjectField()或Set<基本型別>Field()函式進行

   以下是JNI用於獲取例項變數的函式:(來自於標頭檔案jni.h)

  

  此案例所有檔案:

  

  (1)建立Java程式

       

  定義兩個例項變數,一個為基本型別,另一個為物件型別。利用C程式碼對其進行更改,然後輸出結果,校驗其例項變數是否改變。

   (2)編譯Java程式,並生成相關標頭檔案

       

  

   (3)編寫原始檔實現。

   

  根據上述描述的獲取成員變數的步驟進行。

  注:由於String在c語言中沒有直接對映的型別,只能通過相關函式轉換為以'\0'結尾的字元陣列。

   (4)生成動態連結庫,注這裡直接指定庫名為libdemo3.so,至於為何要加字首lib,請看前文

  

   (5)執行Java程式

  

   由圖可知,C程式碼成功改變了Java物件例項變數的值。

 

  

相關文章