<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    走在架構師的大道上 Jack.Wang's home

    Java, C++, linux c, C#.net 技術,軟件架構,領域建模,IT 項目管理 Dict.CN 在線詞典, 英語學習, 在線翻譯

    BlogJava 首頁 新隨筆 聯系 聚合 管理
      195 Posts :: 3 Stories :: 728 Comments :: 0 Trackbacks
     

             JavaC++JNI編程小結
                                   --- jack 于湖大

     1.       什么是 JNI

        JNIJava Native Interface的縮寫。從Java 1.1開始,JNI標準成為java平臺的一部分,它允許Java和其他語言進行交互。JNI一開始為CC++而設計的,但是它并不妨礙你使用其他語言,只要調用約定受支持就可以了。

          使用java與本地已編譯的代碼交互,通常會喪失平臺可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的,比如,使用一些舊的庫,與硬件、操作系統進行交互,或者為了提高程序的性能。

       關于 JNI 的用法很簡單,有點像 java 里的 reflect 的工作機制,有興趣的朋友可以參看更詳細的書

    2.       JNI 開發步驟

    l          編寫帶有native聲明的方法的java

    l          使用javac IDE(JBuilder,eclipse)編譯所編寫的java

    l          使用javah -jni java類名生成擴展名為h的頭文件

    l          使用C++ 實現本地方法,對調用簽名可用 javap –s –p [類全名] 查看(開發 C++ 動態鏈接庫本例是用的 VC6

    注意要從 JDK下面的 include 文件夾中把 jni.h jni_md.h 兩個文件 copy 到你的 VC 工程里

    l          Java load 動態鏈接庫文件,調用 native 方法

    3.       開發實例

    1.        編寫 Java : (我的 IDE eclipse)

    /**

     * Jack.Wang

     */

    package org.jm.jni;

    import java.util.ArrayList;

    /**

     * @author Jack.Wang

     * @time Mar 1, 2008

     */

    public class BackgroundProcess {

       static {

            System.loadLibrary("org_jm_jni_BackgroundProcess");

    }

    // 三個 native 方法和一個 int 變量

        public native boolean checkValid();

        public native void processData(BackgroundProcess bg);

        public native void processGarbage(String[] bg);

        public int num = 5;

        // C++ 中可以調用的方法

        public String backProcess(ArrayList<String> p) {

            System.out.println("這是 Java 里的方法,在 C++ 中調用。");

            System.out.println("這個方法,是 java native checkValid 方法調用的。");

            return "look up process ->" + p;

        }

        public static void main(String[] args) {

            String[] array = new String[4];

            array[0] = "jack";

            array[1] = "maggie";

            array[2] = "rocket";

            array[3] = "tom";

            BackgroundProcess bgP = new BackgroundProcess();

            // 調用 C++ DLL 中定義的方法。

            bgP.checkValid();// 該方法回調 java 中的 backProcess 方法

            bgP.processData(bgP);

            bgP.processGarbage(array);

            // C++ DLL 改變了該變量

            System.out.println("number 現在的值是: " + bgP.num);

        }

    }

    2.        生成 C++ 的頭文件(javah 命令生成,用javap –s –p [類全名] 命令查看java 方法簽名

    /* DO NOT EDIT THIS FILE - it is machine generated */

    #include "jni.h"

    /* Header for class org_jm_jni_BackgroundProcess */

    #ifndef _Included_org_jm_jni_BackgroundProcess

    #define _Included_org_jm_jni_BackgroundProcess

    #ifdef __cplusplus

    extern "C" {

    #endif

    /*

     * Class:     org_jm_jni_BackgroundProcess

     * Method:    checkValid

     * Signature: ()Z

     */

    JNIEXPORT jboolean JNICALL Java_org_jm_jni_BackgroundProcess_checkValid

     (JNIEnv *, jobject);

    /*

     * Class:     org_jm_jni_BackgroundProcess

     * Method:    processData

     * Signature: (Lorg/jm/jni/BackgroundProcess;)V

     */

    JNIEXPORT void JNICALL Java_org_jm_jni_BackgroundProcess_processData

     (JNIEnv *, jobject, jobject);

    /*

     * Class:     org_jm_jni_BackgroundProcess

     * Method:    processGarbage

     * Signature: ([Ljava/lang/String;)V

     */

    JNIEXPORT void JNICALL Java_org_jm_jni_BackgroundProcess_processGarbage

     (JNIEnv *, jobject, jobjectArray);

    #ifdef __cplusplus

    }

    #endif

    #endif

    3.        開發 C++ DLL 的原文件 (記得要加入 jni.h jni_md.h 兩個文件)

    發布 DLL 文件, 我是配置了 path 環境變量

    #include "org_jm_jni_BackgroundProcess.h"

    #include <iostream.h>

    #include <windows.h>

    #include "string.h"

    char* jstringTostring(JNIEnv* env, jstring jstr)

    {

           char* rtn = NULL;

           jclass clsstring = env->FindClass("java/lang/String");

           jstring strencode = env->NewStringUTF("utf-8");

           jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");

           jbyteArray barr= (jbyteArray)env->CallObjectMethod(jstr, mid, strencode);

           jsize alen = env->GetArrayLength(barr);

           jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);

           if (alen > 0)

           {

                     rtn = (char*)malloc(alen + 1);

                     memcpy(rtn, ba, alen);

                     rtn[alen] = 0;

           }

           env->ReleaseByteArrayElements(barr, ba, 0);

           return rtn;

    }

    //char* to jstring

    jstring stoJstring(JNIEnv* env, const char* pat)

    {

           jclass strClass = env->FindClass("Ljava/lang/String;");

           jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");

           jbyteArray bytes = env->NewByteArray(strlen(pat));

           env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);

           jstring encoding = env->NewStringUTF("utf-8");

           return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);

    }

    /*

    * Class:     org_jm_jni_BackgroundProcess

    * Method:    checkValid

    * Signature: ()Z

    */

    JNIEXPORT jboolean JNICALL Java_org_jm_jni_BackgroundProcess_checkValid

    (JNIEnv *env, jobject obj){

    jclass bgpClass=env->GetObjectClass(obj);

    jmethodID methodId=env->GetMethodID(bgpClass,"backProcess","(Ljava/util/ArrayList;)Ljava/lang/String;");

    jobject str=env->CallObjectMethod(obj,methodId,NULL);

    jfieldID fieldId=env->GetFieldID(bgpClass,"num","I");

    jint number=env->GetIntField(obj,fieldId);

    cout << "number 值是: " <<number << endl;

    env->SetIntField(obj,fieldId,100L);

    return 1;    

    }

    /*

    * Class:     org_jm_jni_BackgroundProcess

    * Method:    processData

    * Signature: (Lorg/jm/jni/BackgroundProcess;)V

    */

    JNIEXPORT void JNICALL Java_org_jm_jni_BackgroundProcess_processData

    (JNIEnv *env, jobject, jobject){

    cout<< "this function do nothing " << endl;

    }

    /*

    * Class:     org_jm_jni_BackgroundProcess

    * Method:    processGarbage

    * Signature: ([Ljava/lang/String;)V

    */

    JNIEXPORT void JNICALL Java_org_jm_jni_BackgroundProcess_processGarbage

    (JNIEnv *env, jobject, jobjectArray array){

    jint size=env->GetArrayLength(array);

    cout << "數組大小是: " << size << endl;

    jstring tempObj=NULL;

        char *pszSTR1 = NULL;

    for(int i=0;i<size;i++){

               cout << "current value is : " << i << endl;

               tempObj=(jstring)env->GetObjectArrayElement(array,i);

               const char * chars =env->GetStringUTFChars(tempObj, 0); 

        cout << chars << endl; 

       }

    }

    4.        現在你可以在 Java C++ 之間互調了

     





    本博客為學習交流用,凡未注明引用的均為本人作品,轉載請注明出處,如有版權問題請及時通知。由于博客時間倉促,錯誤之處敬請諒解,有任何意見可給我留言,愿共同學習進步。
    posted on 2008-03-02 08:23 Jack.Wang 閱讀(8933) 評論(4)  編輯  收藏 所屬分類: 開發技術

    Feedback

    # re: Java與C++之JNI編程小結 2008-03-02 14:53 xifu
    田里影院  回復  更多評論
      

    # re: Java與C++之JNI編程小結 2008-03-03 12:29 Jack.Wang
    有問題可以討論  回復  更多評論
      

    # re: Java與C++之JNI編程小結 2008-03-03 12:29 Jack.Wang
    @xifu
    什么意思  回復  更多評論
      

    # re: Java與C++之JNI編程小結 2008-03-07 11:52 rocket
    兩個OO語言寫出來的process式方法。。。
    jack,寫完你就不能用OO重構一下嗎,呵呵  回復  更多評論
      

    主站蜘蛛池模板: 亚洲国产成人久久综合一区77| 自拍偷自拍亚洲精品第1页| 女性无套免费网站在线看| 全亚洲最新黄色特级网站| 亚洲午夜成激人情在线影院| 污网站免费在线观看| 一个人免费观看www视频在线| 亚洲精品无码永久在线观看你懂的| 国产精品亚洲自在线播放页码| 你懂的免费在线观看| 国产做床爱无遮挡免费视频| 亚洲天堂电影在线观看| 91视频免费网站| 亚洲视频在线观看| 三级网站在线免费观看| 亚洲∧v久久久无码精品| 好男人资源在线WWW免费| 国产成人免费片在线视频观看| 亚洲性一级理论片在线观看| 欧美三级在线电影免费| 亚洲综合激情六月婷婷在线观看| 久久久WWW成人免费精品| 又大又粗又爽a级毛片免费看| 亚洲人成网站在线在线观看| 最近2019中文字幕免费直播| 亚洲av色福利天堂| 中文字幕无码播放免费| 亚洲宅男精品一区在线观看| 国产麻豆免费观看91| 国产亚洲精品bv在线观看| 在线观看视频免费完整版| 久久精品国产亚洲av天美18| 国产成人综合久久精品免费| 中文字幕免费在线看电影大全 | 最近免费mv在线电影| 亚洲熟妇AV乱码在线观看| 免费在线看v网址| 亚洲一级毛片在线播放| 日本h在线精品免费观看| 亚洲一区免费视频| 亚洲成a人无码av波多野按摩|