溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux系統(tǒng)中如何使用JNI

發(fā)布時間:2022-01-31 10:45:07 來源:億速云 閱讀:147 作者:小新 欄目:開發(fā)技術

這篇文章將為大家詳細講解有關Linux系統(tǒng)中如何使用JNI,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

JNI是Java Native Interface的縮寫,通過使用 Java本地接口書寫程序,可以確保代碼在不同的平臺上方便移植。從Java1.1開始,JNI標準成為java平臺的一部分,它允許Java代碼和其他語言寫的代碼進行交。

Linux系統(tǒng)中如何使用JNI

我將詳細說明在 Linux 平臺下如何實現本地共享庫與 Java 協同工作,老規(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 關鍵字,如下所示:

public native void SayHello(String strName);

其次:必須顯式地加載本地代碼庫。我們需在類的靜態(tài)塊中加載這個庫(靜態(tài)庫在類加載時候就會調用)

現在我們來編輯hello.java以生成hello.class文件。

生成本地鏈接庫

要為以上定義的類生成 Java 本地接口頭文件,需使用 javah,Java 編譯器的 javah 功能將根據 Hello 類生成必要的聲明,此命令將生成 Hello.h 文件

生成的 Hello.h 文件 內容如下所示:

#include  /* Header for class Hello */#ifndef _Included_Hello#define _Included_Hello#ifdef __cplusplusextern "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

內容如下:

#include "Hello.h"#include  // 與 Hello.h 中函數聲明相同
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;
}

這里有三個參數,下面講一下參數用法:

(1)所有的 JNI 調用都使用了 JNIEnv * 類型的指針,習慣上在 CPP 文件中將這個變量定義為 evn,它是任意一個本地方法的第一個參數。env 指針指向一個函數指針表,在 VC 中可以直接用”->”操作符訪問其中的函數。 (2)jobject 指向在此 Java 代碼中實例化的 Java 對象 LocalFunction 的一個句柄,相當于 this 指針。 (3)第三個參數就是本地調用中有 Java 程序傳進的參數,本例中只有一個 String 型參數。 對于字符串型參數,因為在本地代碼中不能直接讀取 Java 字符串,而必須將其轉換為 C /C++ 字符串或 Unicode。

編譯生成共享庫。

使用 GCC 時 , 必須通知編譯器在何處查找此 Java 本地方法的支持文件,并且顯式通知編譯器生成位置無關的代碼,在我的環(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();
  // 調用本地方法
  h.SayHello("Hello world");    
 }
}

用 javac 編譯A.java,生成A.class 向執(zhí)行普通 Java 程序一樣使用 java A,我們會看到在屏幕上出現 Hello world。 ok,完成!

關于“Linux系統(tǒng)中如何使用JNI”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI