• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-30  評論-67  文章-0  trackbacks-0



            編譯HelloWorld類
             1 public class HelloWorld {
             2     public native void displayHelloWorld();
             3 
             4     public native void printxx(String str);
             5 
             6     static {
             7         System.loadLibrary("hello");
             8         // System.load("hello");
             9     }
            10 
            11     public static void main(String[] args) {
            12         HelloWorld hw = new HelloWorld();
            13         hw.displayHelloWorld();
            14         for (int i = 0;; ++i) {
            15             hw
            16                     .printxx("wo kaowo kaowo kaowo kaowo kaowo kaowo kaowo kaowo kaowo kaowo kao");
            17             if (i % 1000 == 0) {
            18                 try {
            19                     Thread.sleep(10);
            20                 } catch (InterruptedException e) {
            21                 }
            22             }
            23         }
            24     }
            25 }

            對編譯完的class執行
            javah HelloWorld

             1 /* DO NOT EDIT THIS FILE - it is machine generated */
             2 #include <jni.h>
             3 /* Header for class HelloWorld */
             4 
             5 #ifndef _Included_HelloWorld
             6 #define _Included_HelloWorld
             7 #ifdef __cplusplus
             8 extern "C" {
             9 #endif
            10 /*
            11  * Class:     HelloWorld
            12  * Method:    displayHelloWorld
            13  * Signature: ()V
            14  */
            15 JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
            16   (JNIEnv *, jobject);
            17 
            18 /*
            19  * Class:     HelloWorld
            20  * Method:    printxx
            21  * Signature: (Ljava/lang/String;)V
            22  */
            23 JNIEXPORT void JNICALL Java_HelloWorld_printxx
            24   (JNIEnv *, jobject, jstring);
            25 
            26 #ifdef __cplusplus
            27 }
            28 #endif
            29 #endif
            30 

            編譯
            cl -I%java_home%\include -I%java_home%\include\win32 -LDHelloWorld.c -Fehello.dll

             1 #include <jni.h>
             2 #include "HelloWorld.h"
             3 #include <stdio.h>
             4 JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
             5 {
             6 printf("Hello world!\n"); 
             7 return;
             8 }
             9 
            10 JNIEXPORT void JNICALL Java_HelloWorld_printxx
            11   (JNIEnv *env, jobject obj, jstring prompt){
            12 
            13 const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
            14   printf("%s",prompt);
            15 (*env)->ReleaseStringUTFChars(env, prompt, str);
            16   
            17   return;
            18   }
            19   
            20   




            3.Java類型和本地類型對應
              
              在如下情況下,需要在本地方法中應用java對象的引用,就會用到類型之間的轉換:
              
              1)java方法里面將參數傳入本地方法;
              
              2)在本地方法里面創建java對象;
              
              3)在本地方法里面return結果給java程序。
              
              分為如下兩種情況:
              
              Java原始類型
              
              像booleans、integers、floats等從Java程序中傳到本地方法中的原始類型可以直接使用,下面是java中的原始類型和本地方法中的類型的對應:
              
              Java類型  本地類型  字節(bit)
              
              boolean   jboolean   8, unsigned
              byte    jbyte    8
              char    jchar    16, unsigned
              short    jshort    16
              int     jint     32
              long    jlong    64
              float    jfloat    32
              double   jdouble   64
              void    void     n/a
              
              也就是說如果我在方法中傳進去了一個boolean的參數的話,那么我在本地方法中就有jboolean類型與之對應。同理,如果在本地方法中return一個jint的話,那么在java中就返回一個int類型。 中國網管論壇
              
              Java對象
              
              Java對象做為引用被傳遞到本地方法中,所有這些Java對象的引用都有一個共同的父類型jobject(相當于java中的Object類是所有類的父類一樣)。下面是JNI實現的一些jobject的子類:
              
              4.本地方法中訪問java程序中的內容
              
              1)訪問String對象:
              
              從java程序中傳過去的String對象在本地方法中對應的是jstring類型,jstring類型和c中的char*不同,所以如果你直接當做char*使用的話,就會出錯。因此在使用之前需要將jstring轉換成為c/c++中的char*,這里使用JNIEnv的方法轉換。下面是一個例子:
              
              代碼3:
              
              JNIEXPORT jstring JNICALL Java_Prompt_getLine
              (JNIEnv *env, jobject obj, jstring prompt)
              {
              char buf[128];
              const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
              printf("%s", str);
              (*env)->ReleaseStringUTFChars(env, prompt, str);
              
              這里使用GetStringUTFChars方法將傳進來的prompt(jstring類型)轉換成為UTF-8的格式,就能夠在本地方法中使用了。
              
              注意:在使用完你所轉換之后的對象之后,需要顯示調用ReleaseStringUTFChars方法,讓JVM釋放轉換成UTF-8的string的對象的空間,如果不顯示的調用的話,JVM中會一直保存該對象,不會被垃圾回收器回收,因此就會導致內存溢出。

            www.bitsCN.com


              
              下面是訪問String的一些方法:
              
              ◆GetStringUTFChars將jstring轉換成為UTF-8格式的char*
              
              ◆GetStringChars將jstring轉換成為Unicode格式的char*
              
              ◆ReleaseStringUTFChars釋放指向UTF-8格式的char*的指針
              
              ◆ReleaseStringChars釋放指向Unicode格式的char*的指針
              
              ◆NewStringUTF創建一個UTF-8格式的String對象
              
              ◆NewString創建一個Unicode格式的String對象
              
              ◆GetStringUTFLengt獲取UTF-8格式的char*的長度
              
              ◆GetStringLength獲取Unicode格式的char*的長度
              
              2) 訪問Array對象:
              
              和String對象一樣,在本地方法中不能直接訪問jarray對象,而是使用JNIEnv指針指向的一些方法來是用。
              
              訪問Java原始類型數組:
              
              1)獲取數組的長度:
              
              代碼4:
              
              JNIEXPORT jint JNICALL Java_IntArray_sumArray
              (JNIEnv *env, jobject obj, jintArray arr)
              {
              int i, sum = 0;
              jsize len = (*env)->GetArrayLength(env, arr);
              
              如代碼4所示,這里獲取數組的長度和普通的c語言中的獲取數組長度不一樣,這里使用JNIEvn的一個函數GetArrayLength。
            bitsCN_com

              
              2)獲取一個指向數組元素的指針:
              
              代碼4:
              
              jint *body = (*env)->GetIntArrayElements(env, arr, 0);
              
              使用GetIntArrayElements方法獲取指向arr數組元素的指針,注意該函數的參數,第一個是JNIEnv,第二個是數組,第三個是數組里面第三個是數組里面開始的元素
              
              3)使用指針取出Array中的元素
              
              代碼5:
              
              for (i=0; i<len; i++) {
              sum += body[i];
              }
              
              這里使用就和普通的c中的數組使用沒有什么不同了
              
              4)釋放數組元素的引用
              
              代碼6:
              
              (*env)->ReleaseIntArrayElements(env, arr, body, 0);
              
              和操作String中的釋放String的引用是一樣的,提醒JVM回收arr數組元素的引用。
              
              這里舉的例子是使用int數組的,同樣還有boolean、float等對應的數組。
              
              獲取數組元素指針的對應關系:
              
              函數            數組類型
              
              GetBooleanArrayElements   boolean
              GetByteArrayElements    byte
              GetCharArrayElements    char bitsCN.nET中國網管博客
              GetShortArrayElements    short
              GetIntArrayElements     int
              GetLongArrayElements    long
              GetFloatArrayElements    float
              GetDoubleArrayElements   double
              
              釋放數組元素指針的對應關系:
              Function            Array Type
              ReleaseBooleanArrayElements   boolean
              ReleaseByteArrayElements    byte
              ReleaseCharArrayElements    char
              ReleaseShortArrayElements    short
              ReleaseIntArrayElements     int
              ReleaseLongArrayElements    long
              ReleaseFloatArrayElements    float
              ReleaseDoubleArrayElements   double
              
              訪問自定義Java對象數組
              
              The JNI provides a separate set of functions to access elements of object arrays. You can use these functions to get and set individual object array elements.
              
              Note: You cannot get all the object array elements at once.
              
              GetObjectArrayElement returns the object element at a given index.
            www_bitscn_com

              
              SetObjectArrayElement updates the object element at a given index.
              
              3) 訪問Java對象的方法:
              
              在本地方法中調用Java對象的方法的步驟:
              
              ①.獲取你需要訪問的Java對象的類:
              
              jclass cls = (*env)->GetObjectClass(env, obj);
              
              使用GetObjectClass方法獲取obj對應的jclass。
              
              ②.獲取MethodID:
              
              jmethodID mid = (*env)->GetMethodID(env, cls, "callback", "(I)V");
              
              使用GetMethdoID方法獲取你要使用的方法的MethdoID。其參數的意義:
              
              env??>JNIEnv
              
              cls??>第一步獲取的jclass
              
              "callback"??>要調用的方法名
              
              "(I)V"??>方法的Signature
              
              ③.調用方法:
              
              (*env)->CallVoidMethod(env, obj, mid, depth);
              
              使用CallVoidMethod方法調用方法。參數的意義:
              
              env??>JNIEnv
              
              obj??>通過本地方法穿過來的jobject
              
              mid??>要調用的MethodID(即第二步獲得的MethodID)
              
              depth??>方法需要的參數(對應方法的需求,添加相應的參數) bitsCN.nET中國網管博客
              
              注:這里使用的是CallVoidMethod方法調用,因為沒有返回值,如果有返回值的話使用對應的方法,在后面會提到。
              
              方法的Signature
              
              方法的Signature是由方法的參數和返回值的類型共同構成的,下面是他們的結構:
              
              "(argument-types)return-type"
              
              其中Java程序中參數類型和其對應的值如下:
              
              Signature  Java中的類型
              Z       boolean
              B       byte
              C       char
              S       short
              I       int
              J       long
              F       float
              D       double
              L fully-qualified-class;   fully-qualified-class
              
              [ type  type[]
              
              ( arg-types ) ret-type  method type
              
              一個Java類的方法的Signature可以通過javap命令獲取:
              
              javap -s -p Java類名
              
              給調用的函數傳參數:
              
              通常我們直接在methodID后面將要傳的參數添加在后面,但是還有其他的方法也可以傳參數:
              
              CallVoidMethodV可以獲取一個數量可變的列表作為參數; www_bitscn_com
              
              CallVoidMethodA可以獲取一個union。
              
              調用靜態方法:
              
              就是將第二步和第三步調用的方法改為對應的:
              
              GetStaticMethodID獲取對應的靜態方法的ID
              
              CallStaticIntMethod調用靜態方法
              
              調用超類的方法:
              
              用的比較少,自己看啦。^_^。
              
              4)訪問Java對象的屬性:
              
              訪問Java對象的屬性和訪問Java對象的方法基本上一樣,只需要將函數里面的Method改為Field即可





            posted on 2008-01-05 16:17 含笑半步癲 閱讀(997) 評論(0)  編輯 收藏 引用 所屬分類: java
            国内精品伊人久久久久| 五月丁香综合激情六月久久| 麻豆精品久久久一区二区| 久久最新精品国产| 久久精品视频一| 久久se精品一区二区| 国产精品免费久久| 亚洲精品蜜桃久久久久久| 国产精品无码久久四虎| 性欧美大战久久久久久久久| 久久久久四虎国产精品| 久久人人爽人人爽人人爽| 久久国产乱子精品免费女| | 久久久久久亚洲AV无码专区| 久久国产精品99久久久久久老狼| 亚洲国产成人久久综合区| 久久99热精品| 久久精品无码专区免费东京热| 色婷婷久久综合中文久久一本| www.久久热.com| 色婷婷综合久久久久中文一区二区 | 手机看片久久高清国产日韩 | 国产99精品久久| 亚洲午夜无码久久久久| 久久久国产99久久国产一| 久久婷婷人人澡人人| 狠狠色伊人久久精品综合网| 日本免费一区二区久久人人澡| AAA级久久久精品无码片| 无码伊人66久久大杳蕉网站谷歌 | 久久精品国产半推半就| 99久久无码一区人妻a黑| 国内精品人妻无码久久久影院| 亚洲国产精品无码久久久蜜芽| 久久99久久99精品免视看动漫 | 久久中文字幕无码专区| 久久久国产精品| 亚洲精品第一综合99久久| 最新久久免费视频| 97精品国产97久久久久久免费 |