• <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>
            JNI全名是Java Native Interface,通過JNI技術可以實現Java和其他編程語言的互相調用。這里我們使用的是Java和C的互相調用,Java提供本地接口,C實現該本地接口。

            我使用的是RHEL 5,主要是為了測試一下在Linux平臺下,了解JNI技術是如何實現的。通過一個HelloWorld實例,具體過程在下面講解。

            首先,實現的是Java本地接口Hello.java,代碼如下所示:

            class HelloWorld {

                
            public native void sayHello();

                
            static {
                    System.loadLibrary(
            "HelloWorld");
                }


                
            public static void main(String[] args) {
                    (
            new HelloWorld()).sayHello();
                }

            }


            其中,方法聲明為native,其實HelloWorld類就相當于一個接口,是為其他編程語言聲明的接口。System.loadLibrary("HelloWorld");語句是一個static塊,也就是在該HelloWorld類加載的時候進行執行。其中,該語句實現了加載本地的動態連接庫(DLL),在Linux平臺下,動態連接庫文件是以.so作為擴展名的,也就是標準對象(Standard Object)。

            對該本地接口類進行編譯:

            [root@localhost jni]# javac HelloWorld.java

            接著,通過編譯的HelloWorld.class文件,生成C語言的頭文件,執行命令:

            [root@localhost jni]# javah -jni HelloWorld

            可以看到,在當前目錄下生成一個HelloWorld.h文件,該文件就是C的接口文件,為使用C實現Java接口中定義的方法,可以發現在HelloWorld.h中有一個方法聲明:

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

            #ifndef __HelloWorld__
            #define __HelloWorld__

            #include 
            <jni.h>

            #ifdef __cplusplus
            extern "C"
            {
            #endif

            JNIEXPORT 
            void JNICALL Java_HelloWorld_sayHello (JNIEnv *env, jobject);

            #ifdef __cplusplus
            }

            #endif

            #endif /* __HelloWorld__ */

            然后,用C實現該方法,在HelloWorld.c文件中,代碼如下:

            #include <jni.h>
            #include 
            "HelloWorld.h"
            #include 
            <stdio.h>

            JNIEXPORT 
            void JNICALL Java_HelloWorld_sayHello (JNIEnv *env, jobject obj) {
                printf(
            "Hello,the World!!!");
            }


            這里,方法簽名為Java_HelloWorld_sayHello (JNIEnv *env, jobject obj),添加了形參obj,否則無法通過編譯。

            接下來,生成動態連接庫libHelloWorld.so,執行命令:

            [root@localhost jni]# gcc -fPIC -shared -o libHelloWorld.so HelloWorld.c

            可以在當前目錄下看到libHelloWorld.so,動態連接庫文件名稱以lib開頭。將該文件拷貝到usr/lib目錄下面,就可以測試了。

            現在執行如下命令進行測試:

            [root@localhost jni]# java HelloWorld

            輸出如下:

            Hello,the World!!!

            這只是一個非常簡單的例子,主要是了解JNI在Linux下該如何用。在實際應用中,可能會非常復雜,并且要記住,一旦使用了JNI技術,系統的可移植性被破壞了。有些應用中,正是基于這種特性實現,比如限制軟件的傳播使用,保護開發商權益,等等。

            Feedback

            # re: 如何在linux下創建一個簡單的JNI程序HelloWorld  回復  更多評論   

            2010-12-07 13:21 by 楊書童
            http://blog.chinaunix.net/u1/38994/showart_2014236.html

            # re: 如何在linux下創建一個簡單的JNI程序HelloWorld  回復  更多評論   

            2010-12-07 13:27 by 楊書童
            淺析如何將jni類打包package到指定的包路徑中

            淺析ubuntu 8.10下使用jdk6進行jni開發測試

            luther@gliethttp:~/jni$ vim jusbhid.java
            package gliethttp.usb.usbhid; // 使用打包命令package,將jusbhid類打包到gliethttp.usb.usbhid中.
            public class jusbhid
            {
            public native String usbhid_open(int vid, int pid);
            public native String usbhid_sendstring(String id, String command);
            static {
            System.loadLibrary("usbhid");
            }
            }
            luther@gliethttp:~/jni$ javac jusbhid.java -d . // 將會在當前目錄生成包路徑gliethttp/usb/usbhid文件夾,如果
            luther@gliethttp:~/jni$ tree gliethttp/ // 沒有定義-d .那么將直接在當前目錄生成jusbhid.class
            gliethttp/
            `-- usb
            `-- usbhid
            `-- jusbhid.class

            2 directories, 1 file
            luther@gliethttp:~/jni$
            luther@gliethttp:~/jni$ javah gliethttp.usb.usbhid.jusbhid // 生成jni頭文件.h
            luther@gliethttp:~/jni$ ll gliethttp_usb_usbhid_jusbhid.h // 頭文件名為gliethttp_usb_usbhid_jusbhid.h
            -rw-r--r-- 1 luther luther 788 2009-07-31 12:38 gliethttp_usb_usbhid_jusbhid.h
            luther@gliethttp:~/jni$ vim gliethttp_usb_usbhid_jusbhid.h // 可以看到有如下內容,這里來看,加入package gliethttp.usb.usbhid;
            /* DO NOT EDIT THIS FILE - it is machine generated */ // 與直接定義public class gliethttp_usb_usbhid_jusbhid效果一樣
            #include <jni.h> // 類名中符號'_'表示包路徑.
            /* Header for class gliethttp_usb_usbhid_jusbhid */

            #ifndef _Included_gliethttp_usb_usbhid_jusbhid
            #define _Included_gliethttp_usb_usbhid_jusbhid
            #ifdef __cplusplus
            extern "C" {
            #endif
            /*
            * Class: gliethttp_usb_usbhid_jusbhid
            * Method: usbhid_open
            * Signature: (II)Ljava/lang/String;
            */
            JNIEXPORT jstring JNICALL Java_gliethttp_usb_usbhid_jusbhid_usbhid_1open
            (JNIEnv *, jobject, jint, jint);

            /*
            * Class: gliethttp_usb_usbhid_jusbhid
            * Method: usbhid_sendstring
            * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
            */
            JNIEXPORT jstring JNICALL Java_gliethttp_usb_usbhid_jusbhid_usbhid_1sendstring
            (JNIEnv *, jobject, jstring, jstring);

            #ifdef __cplusplus
            }
            #endif
            #endif
            luther@gliethttp:~/jni$ vim jusbhid.c
            // [luther.gliethttp] -- 20090731
            #include <stdio.h>
            #include "gliethttp_usb_usbhid_jusbhid.h"

            JNIEXPORT jstring JNICALL Java_gliethttp_usb_usbhid_jusbhid_usbhid_1open(JNIEnv *env, jclass obj, jint vid, jint pid)
            {
            char buf[512];
            printf("vid=0x%04x pid=0x%04x\n", vid, pid);
            sprintf(buf, "0#1#2#3#4#5\n");
            return (*env)->NewStringUTF(env, buf);
            }

            JNIEXPORT jstring JNICALL Java_gliethttp_usb_usbhid_jusbhid_usbhid_1sendstring(JNIEnv *env, jclass obj, jstring id, jstring command)
            {
            int fd;
            const char *idv;
            const char *commands;
            idv = ((*env)->GetStringUTFChars)(env, id, 0);
            commands = ((*env)->GetStringUTFChars)(env, command, 0);
            fd = atoi(idv);
            printf("[%d] %s\n", fd, commands);
            return (*env)->NewStringUTF(env, "usbhid_sendstring ok!\n");
            }
            luther@gliethttp:~/jni$ gcc -fPIC -I /usr/local/jdk1.6.0_14/include -I /usr/local/jdk1.6.0_14/include/linux -shared -o libusbhid.so jusbhid.c
            luther@gliethttp:~/jni$ export CLASSPATH=.:$CLASSPATH // 如果沒有正常配置jdk的話,需要強硬指定搜索路徑
            luther@gliethttp:~/jni$ sudo vim /etc/profile // 或者追加如下內容,配置jdk環境
            JAVA_HOME=/usr/local/jdk1.6.0_14
            JRE_HOME=/usr/local/jdk1.6.0_14/jre
            CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib
            export JAVA_HOME JRE_HOME CLASSPATH

            luther@gliethttp:~$ source /etc/profile
            luther@gliethttp:~/jni$ vim usbhid_jni_example.java
            import gliethttp.usb.usbhid.*; // 導入CLASSPATH搜索路徑中,路徑為gliethttp/usb/usbhid/下的所有.class包
            public class usbhid_jni_example
            {
            public static void main(String[] args)
            {
            String rets;
            jusbhid hid = new jusbhid();
            rets = hid.usbhid_open(0x1234,0x5678);
            System.out.printf("%s", rets);
            rets = hid.usbhid_sendstring("88", "QWS\r");
            System.out.printf("%s", rets);
            }
            }
            luther@gliethttp:~/jni$ javac usbhid_jni_example.java
            usbhid_jni_example.java:7: cannot access jusbhid
            bad class file: ./jusbhid.java
            file does not contain class jusbhid
            Please remove or make sure it appears in the correct subdirectory of the classpath.
            jusbhid hid = new jusbhid();
            ^
            1 error
            luther@gliethttp:~/jni$ mv jusbhid.java jusbhid.java.raw // 必須去掉當前目錄jusbhid.java,否則javac將提示上面的錯誤
            luther@gliethttp:~/jni$ javac usbhid_jni_example.java
            luther@gliethttp:~/jni$ export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
            luther@gliethttp:~/jni$ java usbhid_jni_example
            vid=0x1234 pid=0x5678
            0#1#2#3#4#5
            [88] QWS
            usbhid_sendstring ok!

            好了我們的jni類package打包分發工作初步探索已經告一段落了,因為有了package概念,
            所以代碼管理就更加容易,可以將一類的代碼全部放入一個package包中.[luther.gliethttp]
            久久精品国产亚洲AV麻豆网站| 久久伊人精品青青草原高清| 无码精品久久一区二区三区| 四虎国产精品成人免费久久| 亚洲国产欧美国产综合久久| yy6080久久| 亚洲国产成人久久综合区| 一本色道久久综合亚洲精品| 丁香久久婷婷国产午夜视频| 欧美精品丝袜久久久中文字幕 | 99热热久久这里只有精品68| 久久综合给合综合久久| 国产一区二区精品久久| 欧美亚洲另类久久综合婷婷| 国内精品久久久久久99| 国产精品99久久久精品无码| 久久精品国产精品国产精品污| 久久久黄色大片| 国产2021久久精品| 97久久香蕉国产线看观看| 久久中文字幕人妻丝袜| 精品乱码久久久久久夜夜嗨 | 国产综合久久久久久鬼色| 亚洲色大成网站WWW久久九九| 久久精品一区二区三区中文字幕| 亚洲中文字幕无码久久精品1| 久久香蕉国产线看观看猫咪?v| 久久噜噜电影你懂的| 欧美熟妇另类久久久久久不卡| 亚洲国产精品无码久久久久久曰| 精品久久久久香蕉网| 亚洲精品无码久久久久| 老司机午夜网站国内精品久久久久久久久 | 久久狠狠高潮亚洲精品| 亚洲国产成人久久精品99| 久久www免费人成精品香蕉| 久久久久久亚洲精品成人| 麻豆精品久久精品色综合| 国产日产久久高清欧美一区| 久久久老熟女一区二区三区| 亚洲va久久久噜噜噜久久男同|