日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux 下 Jni 实现

發布時間:2025/4/5 linux 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 下 Jni 实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近研究Android,涉及到JNI調用。雖然我對Java語言有所了解,但是還沒有接觸過JNI。今天在Unix Center的Ubuntu上面用JNI實現了“經典”的“Hello world”程序。通過這個簡單的程序把JNI的一些小知識進行一下總結。

什么是JNI

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

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

JNI的簡單示例

???? 下面我就用JNI實現一個經典的“Hello World”程序。該程序在Java中通過JNI調用c函數實現“Hello World”的輸出。創建該程序分為以下步驟:

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

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

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

4、創建HelloWorld.c,實現HelloWorld.h定義的函數。

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

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

???? 下面我們就一步一步來實現這個程序。

創建HelloWorld.java

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

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

編譯HelloWorld.java

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

javac HelloWorld.java

在當前文件夾編譯生成HelloWorld.class。

生成HelloWorld.h

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

javah -jni HelloWorld

在當前文件夾中會生成HelloWorld.h。打開HelloWorld.h將會發現如下代碼:

/* 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

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

實現HelloWorld.c

創建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的兩個參數,本例比較簡單,不需要用到這兩個參數。但是這兩個參數在JNI中非常重要。

env代表java虛擬機環境,Java傳過來的參數和c有很大的不同,需要調用JVM提供的接口來轉換成C類型的,就是通過調用env方法來完成轉換的。

obj代表調用的對象,相當于c++的this。當c函數需要改變調用對象成員變量時,可以通過操作這個對象來完成。

編譯生成libHelloWorld.so

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

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

在當前目錄生成libHelloWorld.so。注意一定需要包含Java的include目錄(請根據自己系統環境設定),因為Helloworld.c中包含了jni.h。

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

運行Java程序HelloWorld

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

java HelloWorld

如果你這步發生問題,如果這步你收到java.lang.UnsatisfiedLinkError異常,可以通過如下方式指明共享庫的路徑:

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

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

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

總結

本文只是一個JNI簡單調用,當然JNI還有很多東西需要學習。如有錯誤之處請不吝指教。

參考文章:

在Linux平臺下使用JNI

The Java Native Interface Programmer’s Guide and Specification

JNI編程指南-中文版

總結

以上是生活随笔為你收集整理的Linux 下 Jni 实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。