新聞中心
JNI是Java Native Interface的縮寫,通過使用 Java本地接口書寫程序,可以確保代碼在不同的平臺上方便移植。從Java1.1開始,JNI標準成為java平臺的一部分,它允許Java代碼和其他語言寫的代碼進行交互,本篇文章為大家講解一下Linux系統(tǒng)中使用JNI具體方法。

創(chuàng)新互聯(lián)公司服務(wù)項目包括武隆網(wǎng)站建設(shè)、武隆網(wǎng)站制作、武隆網(wǎng)頁制作以及武隆網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,武隆網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到武隆省份的部分城市,未來相信會繼續(xù)擴大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
我將詳細說明在 Linux 平臺下如何實現(xiàn)本地共享庫與 Java 協(xié)同工作,老規(guī)矩以Hello world為例。
定義一個 Java 類 — Hello類
public class Hello
{
static
{
try
{
// 此處即為本地方法所在鏈接庫名
System.loadLibrary("hello");
}
catch(UnsatisfiedLinkError e)
{
System.err.println( "Cannot load hello library:\n " +
e.toString() );
}
}
public Hello()
{
}
// 聲明的本地方法
public native void SayHello(String strName);
}
這里有兩個注意事項:
首先:為要使用的每個本地方法編寫本地方法聲明,只是必須指定 native 關(guān)鍵字,如下所示:
public native void SayHello(String strName);
其次:必須顯式地加載本地代碼庫。我們需在類的靜態(tài)塊中加載這個庫(靜態(tài)庫在類加載時候就會調(diào)用)
現(xiàn)在我們來編輯hello.java以生成hello.class文件。
生成本地鏈接庫
要為以上定義的類生成 Java 本地接口頭文件,需使用 javah,Java 編譯器的 javah 功能將根據(jù) Hello 類生成必要的聲明,此命令將生成 Hello.h 文件
生成的 Hello.h 文件 內(nèi)容如下所示:
#include
/* Header for class Hello */
#ifndef _Included_Hello
#define _Included_Hello
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Hello
* Method: SayHello
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL Java_Hello_SayHello
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
在與 Hello.h 相同的路徑下創(chuàng)建一個 CPP 文件 Hello.cpp
內(nèi)容如下:
#include "Hello.h"
#include
// 與 Hello.h 中函數(shù)聲明相同
JNIEXPORT void JNICALL Java_Hello_SayHello (JNIEnv * env, jobject arg, jstring instring)
{
// 從 instring 字符串取得指向字符串 UTF 編碼的指針
const jbyte *str =
(const jbyte *)env->GetStringUTFChars( instring, JNI_FALSE );
printf("Hello,%s\n",str);
// 通知虛擬機本地代碼不再需要通過 str 訪問 Java 字符串。
env->ReleaseStringUTFChars( instring, (const char *)str );
return;
}
這里有三個參數(shù),下面講一下參數(shù)用法:
(1)所有的 JNI 調(diào)用都使用了 JNIEnv * 類型的指針,習慣上在 CPP 文件中將這個變量定義為 evn,它是任意一個本地方法的第一個參數(shù)。env 指針指向一個函數(shù)指針表,在 VC 中可以直接用”->”操作符訪問其中的函數(shù)。 (2)jobject 指向在此 Java 代碼中實例化的 Java 對象 LocalFunction 的一個句柄,相當于 this 指針。 (3)第三個參數(shù)就是本地調(diào)用中有 Java 程序傳進的參數(shù),本例中只有一個 String 型參數(shù)。 對于字符串型參數(shù),因為在本地代碼中不能直接讀取 Java 字符串,而必須將其轉(zhuǎn)換為 C /C++ 字符串或 Unicode。
編譯生成共享庫。
使用 GCC 時 , 必須通知編譯器在何處查找此 Java 本地方法的支持文件,并且顯式通知編譯器生成位置無關(guān)的代碼,在我的環(huán)境中按如下過程編譯:
gcc -I/home/jbuilder/jdk1.3.1/include
-I/home/jbuilder/jdk1.3.1/include/linux -fPIC -c Hello.c
生成 Hello.o
gcc -shared -Wl,-soname,libhello.so -o libhello.so Hello.o
生成 libhello.so(這就是linux下動態(tài)鏈接庫的文件名格式,就像windows下是.dll文件后綴名類似)
最后通知動態(tài)鏈接程序此共享文件的路徑。
export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
編寫一個簡單的 Java 程序來測試我們的本地方法
將如下源碼存為 A.java:
import Hello;
import java.util.*;
public class A
{
public static void main(String argv[])
{
A a = new A();
}
public A()
{
Hello h = new Hello();
// 調(diào)用本地方法
h.SayHello("Hello world");
}
}
用 javac 編譯A.java,生成A.class 向執(zhí)行普通 Java 程序一樣使用 java A,我們會看到在屏幕上出現(xiàn) Hello world。 ok,完成!
分享名稱:Linux系統(tǒng)中使用JNI具體方法
文章地址:http://www.dlmjj.cn/article/dhdpjcp.html


咨詢
建站咨詢
