1. 程式人生 > >JNI中呼叫JAVA各種方法詳解

JNI中呼叫JAVA各種方法詳解

總結一下 C 如何 通過 JNI 層呼叫 Java 的靜態和非靜態方法

對於:JNIEXPORT void JNICALL Java_com_example_TestNative_sayHello(JNIEnv * env, jobject thiz, jstring paramString)這樣一個函式 固定引數: JNIEnv *env:JNIEnv代表java環境,通過*env這個指標,就可以讓我們對java層的程式碼進行操作,比如建立java類的物件,呼叫java物件的方法,獲取java物件的屬性等等 這個指標會被JNI傳遞到本地方法的實現函式中來對java端的程式碼進行操作。 jobject thiz:分配給這個類的類載入器 函式引數:
jstring paramString:這是sayHello函式的具體引數,在外部呼叫的時候必須給sayHello函式一個引數,如:sayHello(“Hello JNI”); 呼叫java過程中(重點是呼叫java中的某些類的某些方法) 主要分下面幾個步驟: 1.獲取jclass JNIEnv類中有如下幾個簡單的函式可以取得jclass     jclass FindClass(const char* clsName)  根據類名來查詢一個類,完整類名     jclass GetObjectClass(jobject obj)   根據一個物件,獲取該物件的類
    jclass GetSuperClass(jclass obj)     獲取一個類的父類 FindClass:根據類名來查詢,需要注意的是:這裡的類名是某個類的完整路徑。 如:String這個類    jclass cls_string= (*env)->FindClass(“java/lang/String”); 在用的時候 需要把 . 換成 /  2.獲取類中方法的ID或類屬性的ID JNI在jni.h標頭檔案中定義了jmethodID和jfieldID類表示Java端的方法和屬性 JNIEnv獲取相應的jmethodID和fieldID
的方法: GetMethodID/GetStaticMethodID   獲取一個例項的方法ID/一個靜態的方法ID GetFieldID/GetStaticMethodID         獲取一個例項的域的ID/一個靜態的域的ID GetMethodID原型: jmethodID (JNICALL *GetMethodID)       (JNIEnv *env, jclass clazz, const char *name, const char *sig); 第一個引數預設的*env 第二個引數是獲取到的類 第三個引數是你要獲取的某一個方法的名字 第四個引數是“簽名”,引用這個簽名的作用是對這一函式引數和返回值的描述,對於同一個函式,java是允許對它進行過載的,這時候就必須引入簽名來區分他們3.呼叫方法 JNI同樣提供了呼叫java方法的函式 JNIEnv去呼叫相應java方法的方法有: Call<type>Method/CallStatic<type>Method  這裡的<type>是要呼叫的那個方法的返回值型別 大致有 CallVoidMethod                   CallStaticVoidMethod CallIntMethod                     CallStaticIntMethod CallBooleanMethod              CallStaticBooleanMethod CallByteMethod                   CallStaticByteMethod 如:(*env)->CallVoidMethod(env, obj, jm_id, parameter); 引數一預設的*env 引數二是獲取到的類 引數三是要呼叫的方法的ID 引數四這一方法的引數 方法的簽名: 形如:(引數1型別簽名引數2型別簽名……引數n型別簽名)返回值型別簽名 簽名分兩部分:引數 & 返回值 型別的表述方式有如下對應關係:
12345678910111213型別相應的簽名booleanZbyteBcharCshortSintIlongJfloatFdoubleDvoidVobjectL/分隔包的完整類名:Ljava/lang/String;Array[簽名[I[Ljava/lang/Object;Method(引數1型別簽名引數2型別簽名···)返回值型別簽名

 注:1.object型別的每一個引數最後都得加上”;“2.方法引數或者返回值為java中的物件時,簽名中必須以“L”加上其路徑,不過此路徑必須以“/”分開,自定義的物件也使用本規則例如說 java.lang.String為“java/lang/String”,com.nedu.jni.helloword.Student為”Lcom /nedu/jni/helloword/Student;”3.方法引數或者返回值為陣列型別時,請前加上[例如[I表示 int[],[[[D表示 double[][][],即幾維陣列就加幾個[例項:C
1 2 3 4 5 6 voidf1()()V intf2(int,long)(IJ)I booleanf3(int[])([I)B doublef4(String,int)(Ljava/lang/String;I)D voidf5(int,String[],char)(I[Ljava/lang/String;C)V byte[]f6(int,String,String)(ILjava/lang/String;Ljava/lang/String)[B
下面以幾個例項來重點介紹下方法的簽名的書寫方式 a、呼叫某一個類的建構函式: Java
12345678SecureRandom

相關推薦

JNI呼叫JAVA各種方法

總結一下 C 如何 通過 JNI 層呼叫 Java 的靜態和非靜態方法 對於:JNIEXPORT void JNICALL Java_com_example_TestNative_sayHello(JNIEnv * env, jobject th

Python 在子類呼叫父類方法(單繼承、多層繼承、多重繼承)

測試環境: win7 64位 Python版本:Python 3.3.5 程式碼實踐: 1、在子類中通過“類名”呼叫父類的方法 class FatherA: def __init__(self): print('init

前端學習筆記之jsapply()和call()方法

經過網上的大量搜尋,漸漸明白了apply()和call方法的使用,為此寫一篇文章記錄一下。 定義 apply()方法: Function.apply(obj,args)

Android JNI反射呼叫Java構造方法、成員方法和靜態方法

Android開發中一般講Java介面呼叫放在APP層,但是如果想對外隱藏Java介面呼叫,應該怎麼辦呢?我們可以將介面呼叫放在JNI層,通過反射呼叫所需介面,之後打包成.so庫,這樣既可對外隱藏所有呼叫細節。下面開始講解JNI怎麼呼叫Java方法。 首先

資料爬蟲(三):pythonrequests庫使用方法

一、什麼是Requests Requests 是⽤Python語⾔編寫,基於urllib,採⽤Apache2 Licensed開源協議的 HTTP 庫。它⽐ urllib 更加⽅便,可以節約我們⼤量的⼯作,完全滿⾜HTTP測試需求。 ⼀句話——Python實現的簡單易

Java equals方法

        首先equals方法是object類的方法,所有的類都預設繼承object類,object類也就是所有類的超類。 如果兩個物件進行相等比較,需要呼叫x.equals(y),但是如果沒有重寫equals方法,那麼預設使用的是object類的e

Object類hashCode()和equals()方法(附圖)

 下圖是規範中要求的: 圖解:比如equals相等的箭頭指向hashcode相等,標示equals相等那麼必有hashcode相等。另外有兩個箭頭指向別人的標示可能是其中之一。 //JAVA程式碼: public static void main

JavaScript陣列的基本方法

說明:①在比較第一個引數與陣列中的每一項時,將使用===操作符,即要求查詢的項必須嚴格相等; ②相容性問題,支援的瀏覽器有:IE9 +,FireFox2 +,Chrome,Safari3。 ECMAScript 6為陣列增添的新方法:map(),reduce(),filter() ①map() 語法:arr.

Python3tkinter模組使用方法

轉載自 覆手為雲p 的部落格,附上原文網址,感覺非常有用,存下檔,謝謝幫助~~~ 1、使用tkinter.Tk() 生成主視窗(root=tkinter.Tk()); root.title('標題名')         修改框體的名字,也可在建立時使用classNa

html5 canvas的屬性和方法

建立一個Canvas畫布的方法如下 <canvas id=”canvas” width=”600” height=”400”></canvas> 可以在標籤中新增<canvas>標籤不可用時的替代文字,如下所示: <canv

Android 獲取本地儲存路徑的各種方法

Android 中獲取本地儲存路徑,有四個方法, getCacheDir()、getFilesDir()、getExternalFilesDir()、getExternalCacheDir()。 接下來介紹下每個方法的特點以及路徑地址 getCacheDir(

jni呼叫java方法遇到的bug

今天試了各種方法,想在jni c++的其他執行緒呼叫java層的程式碼,不管是java的靜態方法還是例項的非靜態方法都不行。只要app執行是一執行到呼叫的地方,就奔潰。就只能在native函式的當前執行緒呼叫java方法。然後用c程式碼卻可以。這也太奇怪了。不過我專案用的是

Ext Js 3.2Ext.ajax.request方法

1:Ext.Ajax.request([Object options]):Number     options中的一些屬性和含義如下:     url:指定請求的服務端url    params: 指定要傳遞的引數,可以是一個包含引數名稱及值的物件,也可以是類似於name=

Spark的分區方法

case turn ram key one bound p s ext 查找算法 轉自:https://blog.csdn.net/dmy1115143060/article/details/82620715 一、Spark數據分區方式簡要

Java的main()方法

普通 什麽 javac 無限 reflect ase 理解 jvm cep 在Java中,main()方法是Java應用程序的入口方法,也就是說,程序在運行的時候,第一個執行的方法就是main()方法,這個方法和其他的方法有很大的不同,比如方法的名字必須是main,方法必須

Java 的Stringintern方法及測試樣例

intern public String intern() 返回字串物件的規範化表示形式。 一個初始時為空的字串池,它由類 String 私有地維護。 當呼叫 intern 方法時,如果池已經包含一個等於此 String 物件的字串(該物件由 equals(Obj

JAVA的主函式main方法

main方法詳解 主函式是靜態的 public static void main(String[] args){      } 主函式是什麼:主函式是一個特殊的函式,作為程式的入口,可以被jvm識別。 主函式的定義:   

java的arraycopy(),copyOf()和copyOfRange()方法

java語言提供了很多的方法來對陣列進行復制。其中我們常用的方法有三種,下面一一列舉出來 1. arraycopy()方法 函式原型:arraycopy(Object src, int srcPos, Object dest, int destPos, int length) src: 原陣列

JavaNullPointerException異常的原因以及解決方法

NullPointerException是當您嘗試使用指向記憶體中空位置的引用(null)時發生的異常,就好像它引用了一個物件一樣。 當我們宣告引用變數(即物件)時,實際上是在建立指向物件的指標。考慮以下程式碼,您可以在其中宣告基本型別的整型變數x: int x; x = 10; 在

Java的equals和hashCode方法

Java中的equals方法和hashCode方法是Object中的,所以每個物件都是有這兩個方法的,有時候我們需要實現特定需求,可能要重寫這兩個方法,今天就來介紹一些這兩個方法的作用。 equa