jni應用(如何訪問方法Java的類)
本文將通過例項來說明如何在jni 訪問Java的類和成員。開始先介紹所有物件分類的方法,最後才是例項說明。
訪問物件的屬性和方法
1、例項屬性的訪問
jfieldID GetFieldID (JNIEnv*env, jclass clazz, const char *name, const char*sig);
功能:返回類的例項(非靜態)域的屬性 ID。該域由其名稱及簽名指定。訪問器函式的Get<type>Field及 Set<type>Field
系列使用域 ID檢索物件域。GetFieldID()不能用於獲取陣列的長度域。應使用
引數: env:JNI介面指標。
clazz:Java類物件。
name:該屬性的Name名稱
sig:該屬性的域簽名。
返回值:屬性ID。如果操作失敗,則返回NULL。
丟擲: NoSuchFieldError:如果找不到指定的域。
ExceptionInInitializerError:如果由於異常而導致類初始化程式失敗。
OutOfMemoryError:如果系統記憶體不足。
Get<type>Field
NativeType Get<type>Field (JNIEnv*env, jobject obj, jfieldIDfieldID);
功能:該訪問器例程系列返回物件的例項(非靜態)域的值。要訪問的域由通過呼叫GetFieldID()而得到的域 ID 指定。
引數: env:JNI介面指標。
obj:Java物件(不能為 NULL)。
fieldID:有效的域 ID。
返回值:屬性的內容。
Get<type>Field例程名本地型別
GetObjectField() jobject
GetBooleanField() jboolean
GetByteField() jbyte
GetCharField() jchar
GetShortField() jshort
GetIntField() jint
GetLongField() jlong
GetFloatField() jfloat
GetDoubleField() jdouble
Set<type>Field 方法族
void Set<type>Field (JNIEnv *env, jobject obj, jfieldIDfieldID, NativeTypevalue);
功能:該訪問器例程系列設定物件的例項(非靜態)屬性的值。要訪問的屬性由通過呼叫SetFieldID()而得到的屬性 ID指定。
引數: env:JNI介面指標。
obj:Java物件(不能為 NULL)。
fieldID:有效的域 ID。
value:域的新值。
方法族如下:
Set<type>Field 方法族本地型別
SetObjectField() jobject
SetBooleanField() jboolean
SetByteField() jbyte
SetCharField() jchar
SetShortField() jshort
SetIntField() jint
SetLongField() jlong
SetFloatField() jfloat
SetDoubleField() jdouble
2、靜態屬性的訪問 :也存在相同的方法,
jfieldID GetStaticFieldID (JNIEnv *env,jclass clazz, const char *name, const char*sig);
NativeType GetStatic<type>Field (JNIEnv*env,jclass classzz , jfieldIDfieldID);
voidSetStatic<type>Field (JNIEnv *env,jclassclasszz, jfieldIDfieldID, NativeTypevalue);
它們與例項屬性的唯一區別在於第二個引數jclass classzz代表的是類引用,而不是類例項。
3、呼叫例項方法
jmethodID GetMethodID(JNIEnv *env, jclass clazz, const char*name, const char *sig);
功能:返回類或介面例項(非靜態)方法的方法 ID。方法可在某個 clazz 的超類中定義,也可從 clazz繼承。該方法由其名稱
和簽名決定。 GetMethodID()可使未初始化的類初始化。要獲得建構函式的方法 ID,應將 <init>作為方法名,同時將
void (V)作為返回型別。
引數: env:JNI介面指標。
clazz:Java類物件。
name:方法名。
sig:方法的簽名。
返回值:方法 ID,如果找不到指定的方法,則為 NULL。
丟擲: NoSuchMethodError:如果找不到指定方法。
ExceptionInInitializerError:如果由於異常而導致類初始化程式失敗。
OutOfMemoryError:如果系統記憶體不足。
Call<type>Method例程、Call<type>MethodA例程、Call<type>MethodV例程
NativeType Call<type>Method (JNIEnv*en v, jobject obj , jmethodIDmethodID, ...); //引數附加在函式後面,
NativeType Call<type>MethodA (JNIEnv *env, jobject obj, jmethodID methodID,jvalue *args); //引數以指標形式附加
NativeType Call<type>MethodV (JNIEnv *env, jobject obj,jmethodID methodID, va_listargs); //引數以"連結串列"形式附加
說明:這三個操作的方法用於從本地方法呼叫Java例項方法。它們的差別僅在於向其所呼叫的方法傳遞引數時所用的機制。
這三個操作將根據所指定的方法 ID呼叫 Java 物件的例項(非靜態)方法。引數 methodID必須通過呼叫 GetMethodID()
來獲得。當這些函式用於呼叫私有方法和建構函式時,方法 ID必須從obj 的真實類派生而來,而不應從其某個超類派生。
當然,附加引數可以為空。
引數: env:JNI介面指標。
obj:Java物件。
methodID:方法 ID。
返回值:返回呼叫 Java方法的結果。
丟擲:執行 Java方法時丟擲的異常。
下表根據結果型別說明了各個方法型別。使用者應將Call<type>Method中的 type 替換為所呼叫方法的Java 型別(或使用表
中的實際方法名),同時將 NativeType替換為該方法相應的本地型別。省略掉了其他兩種型別。
Java層返回值方法族本地返回型別NativeType
返回值為void:CallVoidMethod() A / V (無)
返回值為引用型別: CallObjectMethod( ) jobect
返回值為boolean: CallBooleanMethod ( ) jboolean
返回值為byte: CallByteMethod( ) jbyte
返回值char : CallCharMethod( ) jchar
返回值short CallShortMethod() jshort
返回值為int : CallIntMethod() jint
返回值為long: CallLongMethod() jlong
返回值為float: CallFloatMethod() jfloat
返回值為double: CallDoubleMethod() jdouble
4、呼叫靜態方法:也存在如下方法群,
jfieldID GetStaticMethodID (JNIEnv *env,jclass clazz, const char *name, const char*sig);
NativeType Call<type>Method (JNIEnv*env,jclass
classzz , jfieldIDfieldID);
例項如下:
Java 的類如下:
/***test class 需要測試的jni裡訪問的類********/
public class testTime{
public int mVersion;
private int year;
private int month;
private int day;
private int hour;
private int minute;
private int second;
private int reserved;
public
byte[] channelCdata = new byte[1024];
public testTime()
{
}
public
void setTdtDate(int mYear, int mMonth, int mDay)
{
this.year = mYear;
this.month = mMonth;
this.day = mDay;
}
public
void setTdtTime(int mHour, int mMinute, int mSecond)
{
this.hour = mHour;
this.minute = mMinute;
this.second = mSecond;
}
public
void SetCharArray(byte[] cData, int data_size)
{
if (data_size == 0) {
return;
}
byte[] buffer = new byte[data_size];
System.arraycopy(cData, 0, buffer, 0, data_size);
String charText= new String(buffer);
}
public
byte[] getCharArray()
{
String myNane = "gchen"
byte[] charArray = myNane.getBytes();
return charArray;
}
}
/***************jni java class***********************/
package android.com.test;
public class jniTest{
public
native final int jni2JavaClass(Object objTestTime);
static
{
Log.i(TAG, "load testjni lib");
System.loadLibrary("testjni");
}
public jniTest()
{
}
public testJniCallJava()
{
testTime mtim = newtestTime();
jni2JavaClass((Object)mtim);
}
}
/***************jni cpp***********************/
static const char *classPathName = "android/com/test/jniTest";
static JNINativeMethod methods[] = {
{ "jni2JavaClass", "(Ljava/lang/Object;)I", (void *)android_com_test_jniTest_jni2JavaClass},
};
int android_com_test_jniTest_jni2JavaClassJNIEnv *env, jobject thiz,jobjectobjTestTime)
{
int ret = -1;
jclass
testTime= env->GetObjectClass(objTestTime); /********獲取Java的類引用*********/
if (testTime== NULL) {
return ret;
}
jfieldID mfield = env->GetFieldID(testTime, "mVersion", "I");/**********獲取Java的成員以及型別**************/
int version = env->GetIntField(objTestTime,mfield);/**********訪問Java的成員,讀取**************/
env->SetIntField(objTestTime,(jin)0x00)
;;/**********訪問Java的成員,設定**************/
jmethodID
mMethodld == env->GetMethodID(testTime, "setTdtDate",
"(III)V"); /**********獲取Java的方法以及型別**************/
env->CallVoidMethod(objTestTime,mMethodld,
2016, 01,01); /**********呼叫Java的方法**************/
mMethodld== env->GetMethodID(testTime,
"setTdtTime", "(III)V");
env->CallVoidMethod(objTestTime,mMethodld,
9, 30,30);
char mycontry[20] = "China"
jbyteArray byteArray;
jint cDataSize = strlen(mycontry);
byteArray = env->NewByteArray(cDataSize);
env->SetByteArrayRegion(byteArray, (jsize)0, (jsize)cDataSize, (jbyte *)mycontry);
mMethodld = env->GetMethodID(testTime,
"SetCharArray", "([BI)V");/**********獲取Java的方法以及型別**************/
env->CallVoidMethod(objTestTime,
mMethodld,byteArray, cDataSize); /**********訪問Java的方法**************/
env->DeleteLocalRef(byteArray);
char myname[20] = "";
mMethodld = env->GetMethodID(testTime,
"getCharArray", "()[B");
/**********獲取Java的方法以及型別**************/
byteArray = (jbyteArray)env->CallObjectMethod(objTestTime,
mMethodld);/**********訪問Java的方法**************/
jsize arrayLen = env->GetArrayLength(byteArray);
if (arrayLen > 0) {
env->GetByteArrayRegion(byteArray, (jsize)0, (jsize)arrayLen,
(jbyte *)myname);
}
env->DeleteLocalRef(byteArray);
byte data[1024];
mfield = env->GetFieldID(testTime,
"channelCdata", "[B"); /**********獲取Java的成員以及型別**************/
jbyteArray chCdata = (jbyteArray)env->GetObjectField(objTestTime,
mfield);
env->GetByteArrayRegion(chCdata, (jsize)0, (jsize)1024, (jbyte *)data);
env->SetByteArrayRegion(chCdata, (jsize)0, (jsize)1024, (jbyte *)data);/**********訪問Java的成員,設定**************/
}
相關推薦
jni應用(如何訪問方法Java的類)
本文將通過例項來說明如何在jni 訪問Java的類和成員。開始先介紹所有物件分類的方法,最後才是例項說明。 訪問物件的屬性和方法 1、例項屬性的訪問 jfieldID GetFieldID (JNIEnv*env, jclass clazz, const char
java技術學習路徑之:Javaweb監聽器總結(應用場景、方法、配置)
配置 包名 quest ner web.xml 監聽器接口 tty 數據 XML JavaWeb中,監聽器是一種組件,能夠監聽項目的啟動和停止,用戶會話的創建和銷毀,以及各種組件的添加、更新和刪除,能夠通過監聽對象的狀態改變,自動做出反應執行響應代碼。 應用場景: 啟動網站
最簡單打增量包的方法(已附上打包的java類)
前言: 打增量包的目的是快捷打包出項目兩次更新版本之間的差異檔案(除了打包出新增檔案,還能打包出原有已經被改變的檔案)。 問題1: 打包出這些增量檔案有什麼作用? 答:快速部署這些增量檔案到tomcat的webapps資料夾對應的專案中。進行增量部署。 問題2: 打包的工具是什麼?
Java面向對象(繼承、抽象類)
調用父類 找到 如何 包含 抽取 代碼 創建對象 編號 間接 面向對象 今日內容介紹 u 繼承 u 抽象類 第1章 繼承 1.1 繼承的概念 在現實生活中,繼承一般指的是子女繼承父輩的財產。在程序中,繼承描述的是事物之間的所屬關系,通過繼承可以使多種事物之間形成一種關系體
背水一戰 Windows 10 (73) - 控件(控件基類): UIElement - 拖放的基本應用, 手動開啟 UIElement 的拖放操作
mar blink don mes read err agent 傳遞 ams 原文:背水一戰 Windows 10 (73) - 控件(控件基類): UIElement - 拖放的基本應用, 手動開啟 UIElement 的拖放操作[源碼下載] 背水一戰 Windows
利用封裝的思想,描述人類這個抽象的類。(屬性方法自擬)
void source alt aos print person static his urn package kaoshi; public class two {public static void main(String[] args) { Person xm=new
JS筆記—關於類的靜態屬性的繼承(call方法的運用)
網上看了不少,感覺廢話都太多,抓不住重點,下面單刀直入。 一、先弄清楚對於物件而言call()方法的語法 obj1.obj1's function.call(obj2,parameter1,parameter2,......) 作用:讓obj2代替
少說話多寫程式碼之Python學習050——類的成員(靜態方法,類成員方法,getattr,setattr)
我們在訪問類的欄位時,還有一些過濾的條件,類似於前端語言比如vue Js、anjularJs中過濾器的概念。在3.0以前可以使用比如,__setattr__,__getattr__的方法進行屬性的過濾。在3.0以後我們如果對某些欄位需要過濾訪問,也可以使用這些函式。 class Rectan
伴生類和伴生物件(apply方法的實踐)
具有相同名字的object和class,分別為伴生物件和伴生類 1 class ApplyTest { //伴生類 2 3 } 4 5 object ApplyTest { //伴生物件 6 7 } 補充程式碼: object ApplyApp { def main(a
java實現錄入學生成績,升序排列後輸出(陣列升序 Arrays類)
Arrays.sort(score) //陣列升序 實現: package com.array.test; import java.util.Arrays; import java.util.Scanner; /** * 錄入學生成績,升序排列後輸出 */
java 獲取 泛型型別(介面及超類)
package generic.portal; /** * Created by Administrator on 2017/1/10. */ public interface GenericInterface<T> { } package gener
bean配置的三種方式(XML、註解、Java類)介紹與對比
如此的話,我們便不在需要在XML當中顯式使用bean來進行bean的配置。Spring容器在初始化的時候便會自動掃描base-package所指定的包以及子包下面的所有class檔案。所有標註為Repository的類將被自動註冊為bean。
(org.json.JSONObject類)java使用JSONObject讀取json檔案,出現中文亂碼
出現問題的程式碼 //從json檔案中讀取資料 StringBuffer stringBuffer = new StringBuffer(); try { BufferedReader bufferedReader = new BufferedReader(ne
interface 與abstract class(介面 與 抽象類)的特點以及區別,以及應用場景
一、抽象類(abstract) 1、抽象類不能被例項化,如果例項化就會報錯,編譯無法通過。只有抽象類的非抽象子類可以建立物件。 2、抽象類中不一定含有抽象方法,但是有抽象方法的類一定是抽象類。 3、抽象類中的抽象方法只能宣告,不包含方法體,就是不會給出方法的具體實現
什麼時候使用類方法呢?(靜態方法何時使用)
如果某些操作不依賴具體例項,那它就是靜態的,反之如果某些操作是依賴具體例項的(例如訪問一個特定會員的名稱),那它就應該是例項化的。靜態方法不用new物件可以直接呼叫 1.與類相關與物件無關 2.不需要物件的“輕”方法 3.工廠方法 如果某個方法是用頻率較高,或者方法本身通用性較強,無需初始化類成員變數
Mac電腦使用:您的安全性偏好設定僅允許安裝來自App Store和被認可的開發者的應用(解決方法)
昨天準備給電腦上安裝“SEED”,然後別人給我一個壓縮包安裝,結果安裝之後,開啟軟體卻彈出提示框,提示“打不開SEED,因為它來自身份不明的開發者。 。。。”,點選“好”,彈框關閉,SEED卻打不開。 一、 造成有這種提示的原因是由
Java學習筆記31(IO:Properties類)
文本 字符串 存在 設備 操作 筆記 開頭 read 無法 Properties類,表示一個持久的j集,可以存在流中,或者從流中加載 是Hashtable的子類 map集合的方法都能用 用途之一:在開發項目中,我們最後交給客戶的是一個編譯過的class文件,客戶
DelegatingFilterProxy(委派過濾器代理類)使用
targe erp fly lan javaee java ee word tin ava 本文轉自:http://blog.csdn.net/flyingfalcon/article/details/8543898 DelegatingFilterProxy就是一個對於s
Spring Batch 簡單應用(CSV文件操作)(二)
分享 resultset hunk tid XML component files lin 實現 本文將通過一個完整的實例,與大家一起討論運用Spring Batch對CSV文件的讀寫操作。此實例的流程是:讀取一個含有四個字段的CSV文件(ID,Name,Age,Score
背水一戰 Windows 10 (67) - 控件(控件基類): DependencyObject - CoreDispatcher, 依賴屬性的設置與獲取, 依賴屬性的變化回調
protected getprop prop 依賴屬性 其他 優先級 dto type 核心 [源碼下載] 背水一戰 Windows 10 (67) - 控件(控件基類): DependencyObject - CoreDispatcher, 依賴屬性的設置與獲取, 依賴