久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Linux下JNI實現(xiàn)

 MikeDoc 2011-08-19
 最近研究Android,,涉及到JNI調(diào)用。雖然我對Java語言有所了解,,但是還沒有接觸過JNI,。今天在Unix Center的Ubuntu上面用JNI實現(xiàn)了“經(jīng)典”的“Hello world”程序,。通過這個簡單的程序把JNI的一些小知識進行一下總結(jié)。

什么是JNI

JNI是Java native interface的簡寫,,可以譯作Java原生接口,。Java可以通過JNI調(diào)用C/C++的庫,這對于那些對性能要求比較高的Java程序無疑是一個福音,。

使用JNI也是有代價,。大家都知道JAVA程序是運行在JVM之上的,可以做到平臺無關(guān),。但是如果Java程序通過JNI調(diào)用了原生的代碼(比如c/c++等),,則Java程序就喪失了平臺無關(guān)性。最起碼需要重新編譯原生代碼部分,。所以應(yīng)用JNI需要好好權(quán)衡,,不到萬不得已,請不要選擇JNI,,可以選擇替代方案,,比如TCP/IP進行進程間通訊等等。這也是為什么谷歌的Android平臺的底層雖然用JNI實現(xiàn),,但是他不建議開發(fā)人員用JNI來開發(fā)Android上面的應(yīng)用的原因,。將會喪失Android上面的應(yīng)用程序平臺無關(guān)性。

JNI的簡單示例

下面我就用JNI實現(xiàn)一個經(jīng)典的“Hello World”程序,。該程序在Java中通過JNI調(diào)用c函數(shù)實現(xiàn)“Hello World”的輸出,。創(chuàng)建該程序分為以下步驟:

1、創(chuàng)建一個Java程序(HelloWorld.java)定義原生的c/c++函數(shù),。

2,、用javac編譯HelloWorld.java生成HelloWorld.class。

3,、用javah帶-jni參數(shù)編譯HelloWorld.class生成HelloWorld.h文件,,該文件中定義了c的函數(shù)原型。在實現(xiàn)c函數(shù)的時候需要,。

4,、創(chuàng)建HelloWorld.c,實現(xiàn)HelloWorld.h定義的函數(shù),。

5,、編譯HelloWorld.c生成libHelloWorld.so。

6,、在java虛擬機運行java程序HelloWorld,。

下面我們就一步一步來實現(xiàn)這個程序。

創(chuàng)建HelloWorld.java

class HelloWorld
{
private native void print();
public static void main(String[] args)
{
new HelloWorld().print();
}
static
{
System.loadLibrary("HelloWorld");
}
}

注意print方法的聲明,,關(guān)鍵字native表明該方法是一個原生代碼實現(xiàn)的,。另外注意static代碼段的System.loadLibrary調(diào)用,,這段代碼表示在程序加載的時候,自動加載libHelloWorld.so庫,。

編譯HelloWorld.java

在命令行中運行如下命令:

javac HelloWorld.java

在當(dāng)前文件夾編譯生成HelloWorld.class,。

生成HelloWorld.h

在命令行中運行如下命令:

javah -jni HelloWorld

在當(dāng)前文件夾中會生成HelloWorld.h。打開HelloWorld.h將會發(fā)現(xiàn)如下代碼:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class:     HelloWorld
* Method:    print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif

該文件中包含了一個函數(shù)Java_HelloWorld_print的聲明,。這里面包含兩個參數(shù),,非常重要,后面講實現(xiàn)的時候會講到,。

實現(xiàn)HelloWorld.c

創(chuàng)建HelloWorld.c文件輸入如下的代碼:

#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT void JNICALL
Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
}

注意必須要包含jni.h頭文件,,該文件中定義了JNI用到的各種類型,宏定義等,。

另外需要注意Java_HelloWorld_print的兩個參數(shù),,本例比較簡單,不需要用到這兩個參數(shù),。但是這兩個參數(shù)在JNI中非常重要,。

env代表java虛擬機環(huán)境,,Java傳過來的參數(shù)和c有很大的不同,,需要調(diào)用JVM提供的接口來轉(zhuǎn)換成C類型的,就是通過調(diào)用env方法來完成轉(zhuǎn)換的,。

obj代表調(diào)用的對象,,相當(dāng)于c++的this。當(dāng)c函數(shù)需要改變調(diào)用對象成員變量時,,可以通過操作這個對象來完成,。

編譯生成libHelloWorld.so

在Linux下執(zhí)行如下命令來完成編譯工作:

cc -I/usr/lib/jvm/java-6-sun/include/linux/
-I/usr/lib/jvm/java-6-sun/include/
-fPIC -shared -o libHelloWorld.so HelloWorld.c

在當(dāng)前目錄生成libHelloWorld.so。注意一定需要包含Java的include目錄(請根據(jù)自己系統(tǒng)環(huán)境設(shè)定),,因為Helloworld.c中包含了jni.h,。

另外一個值得注意的是在HelloWorld.java中我們LoadLibrary方法加載的是“HelloWorld”,可我們生成的Library卻是libHelloWorld,。這是Linux的鏈接規(guī)定的,,一個庫的必須要是:lib+庫名+.so。鏈接的時候只需要提供庫名就可以了,。

運行Java程序HelloWorld

大功告成最后一步,,驗證前面的成果的時刻到了:

java HelloWorld

如果你這步發(fā)生問題,如果這步你收到j(luò)ava.lang.UnsatisfiedLinkError異常,,可以通過如下方式指明共享庫的路徑:

java -Djava.library.path='.' HelloWorld

當(dāng)然還有其他的方式可以指明路徑請參考《在Linux平臺下使用JNI》,。

我們可以看到久違的“Hello world!”輸出了。

總結(jié)

本文只是一個JNI簡單調(diào)用,,當(dāng)然JNI還有很多東西需要學(xué)習(xí),。如有錯誤之處請不吝指教,。

參考文章:

在Linux平臺下使用JNI

The Java Native Interface Programmer’s Guide and Specification

JNI編程指南-中文版

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多