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

創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括武隆網(wǎng)站建設(shè)、武隆網(wǎng)站制作、武隆網(wǎng)頁(yè)制作以及武隆網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,武隆網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到武隆省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
我將詳細(xì)說(shuō)明在 Linux 平臺(tái)下如何實(shí)現(xiàn)本地共享庫(kù)與 Java 協(xié)同工作,老規(guī)矩以Hello world為例。
定義一個(gè) Java 類 — Hello類
public class Hello
{
static
{
try
{
// 此處即為本地方法所在鏈接庫(kù)名
System.loadLibrary("hello");
}
catch(UnsatisfiedLinkError e)
{
System.err.println( "Cannot load hello library:\n " +
e.toString() );
}
}
public Hello()
{
}
// 聲明的本地方法
public native void SayHello(String strName);
}
這里有兩個(gè)注意事項(xiàng):
首先:為要使用的每個(gè)本地方法編寫本地方法聲明,只是必須指定 native 關(guān)鍵字,如下所示:
public native void SayHello(String strName);
其次:必須顯式地加載本地代碼庫(kù)。我們需在類的靜態(tài)塊中加載這個(gè)庫(kù)(靜態(tài)庫(kù)在類加載時(shí)候就會(huì)調(diào)用)
現(xiàn)在我們來(lái)編輯hello.java以生成hello.class文件。
生成本地鏈接庫(kù)
要為以上定義的類生成 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)建一個(gè) 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);
// 通知虛擬機(jī)本地代碼不再需要通過(guò) str 訪問(wèn) Java 字符串。
env->ReleaseStringUTFChars( instring, (const char *)str );
return;
}
這里有三個(gè)參數(shù),下面講一下參數(shù)用法:
(1)所有的 JNI 調(diào)用都使用了 JNIEnv * 類型的指針,習(xí)慣上在 CPP 文件中將這個(gè)變量定義為 evn,它是任意一個(gè)本地方法的第一個(gè)參數(shù)。env 指針指向一個(gè)函數(shù)指針表,在 VC 中可以直接用”->”操作符訪問(wèn)其中的函數(shù)。 (2)jobject 指向在此 Java 代碼中實(shí)例化的 Java 對(duì)象 LocalFunction 的一個(gè)句柄,相當(dāng)于 this 指針。 (3)第三個(gè)參數(shù)就是本地調(diào)用中有 Java 程序傳進(jìn)的參數(shù),本例中只有一個(gè) String 型參數(shù)。 對(duì)于字符串型參數(shù),因?yàn)樵诒镜卮a中不能直接讀取 Java 字符串,而必須將其轉(zhuǎn)換為 C /C++ 字符串或 Unicode。
編譯生成共享庫(kù)。
使用 GCC 時(shí) , 必須通知編譯器在何處查找此 Java 本地方法的支持文件,并且顯式通知編譯器生成位置無(wú)關(guān)的代碼,在我的環(huán)境中按如下過(guò)程編譯:
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下動(dòng)態(tài)鏈接庫(kù)的文件名格式,就像windows下是.dll文件后綴名類似)
最后通知?jiǎng)討B(tài)鏈接程序此共享文件的路徑。
export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
編寫一個(gè)簡(jiǎn)單的 Java 程序來(lái)測(cè)試我們的本地方法
將如下源碼存為 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,我們會(huì)看到在屏幕上出現(xiàn) Hello world。 ok,完成!
文章標(biāo)題:Linux系統(tǒng)中使用JNI具體方法
文章位置:http://m.fisionsoft.com.cn/article/dhdpjcp.html


咨詢
建站咨詢
