成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

初識 JNI

chavesgu / 2660人閱讀

摘要:初識本地接口概述是用于和本地代碼進(jìn)行交互操作的。針對的是語言,而不是。當(dāng)然,最初也有運(yùn)行的比較慢的原因,但隨著的不斷發(fā)展,編寫的代碼有時已經(jīng)不遜于一些的代碼了。聲明通過關(guān)鍵字標(biāo)識,提醒編譯器該方法在外部定義。

初識 JNI
JNI, Java Native Interface(Java本地接口).
概述

JNI 是用于和本地 C 代碼進(jìn)行交互操作的API。實(shí)際上可以通過許多語言編寫,如C++、C#,本質(zhì)上 Java 調(diào)用的是 dll/so 庫 。此處說是和本地 C 代碼互操作是因?yàn)?JNI API的支持。JNI API針對的是 C 語言,而不是Java。

JNI 的出現(xiàn)的原因有一些是為了彌補(bǔ)一些無法通過 Java 平臺實(shí)現(xiàn)的功能。比如 Windows 的注冊表,這是 Windows 獨(dú)有的東西,Java 并沒有現(xiàn)成可以操作它的 API。

也有一些原因是非 Java 語言編寫的代碼已經(jīng)經(jīng)過了大量的測試,無需重新用 Java 實(shí)現(xiàn)一套。

當(dāng)然,最初也有 JVM 運(yùn)行的比較慢的原因,但隨著 JVM 的不斷發(fā)展,Java編寫的代碼有時已經(jīng)不遜于一些 C/C++ 的代碼了。

JNI 有著上述的一些好處,隨著而來的是它會帶來相應(yīng)語言的缺點(diǎn),
比如會引入 C 語言的無效指針造成的內(nèi)存覆寫問題等等。

所以說 JNI 實(shí)際上使用范圍相對較窄,Web 后端方面用的比較少,安卓端用的相對更多一點(diǎn)。

示例 Hello World

以下為一個簡單的示例

Java 部分

首先在在 Java 中聲明 dll/so 庫中定義的函數(shù)。
聲明通過 native 關(guān)鍵字標(biāo)識,提醒編譯器該方法在外部定義。

// 為了簡單,此處沒有package
public class HelloNative {
  public static native void greeting();
}
C 部分

然后在 C 中定義函數(shù),函數(shù)名有如下要求:

Java_包名_類名_方法名 。(其中的.號都要改為 _下劃線)

如果類名中含有非 ASCII 碼值,或說大于 uoo7F 的 Unicode 字符,用 _0xxxx 來代替。
xxxx 是該字符的Unicode值的4個十六進(jìn)制數(shù)序列)

方法重載需要在名稱后加兩個下劃線,后再加上已編碼的類型。

為了避免在函數(shù)定義時候出錯,Java 提供了 javah 工具完成函數(shù)名的編寫操作。
javah 是通過類文件來生成相應(yīng)的文件的,所以源代碼必須要先編譯才可以。

javah HelloNative

通過如上命令,會生成一個 HelloNative.h 的文件,這個文件包含了 greeting() 方法的聲明。
復(fù)制該文件,改為 .c 文件,去掉一些不需要的東西,然后包含 #include "HelloNative.h" 即可。
然后將方法聲明改為方法實(shí)現(xiàn),在方法實(shí)現(xiàn)中編寫具體的代碼。

JNIEXPORT void JNICALL Java_HelloNative_greeting (JNIEnv* env, jclass cl) {
  printf("Hello Native World!");
}

之后就是編譯代碼了,此處僅粘貼個人測試過的命令,為 Windows 上的 MinGW64 上的 gcc 。

gcc -I "jdk/include" -I "jdk/include/win32" -D __int64="long long" -shared -o HelloNative.dll HelloNative.c

關(guān)于 -D __int64="long long" 參數(shù)的說明:

Windows 上的 jni_md.h 含有聲明 typedef __int64 jlong; ,它專用于 cl 的。如果使用 gcc 需要設(shè)置 -D __int64="long long"
或者也可以修改此文件,如:

#ifdef __GNUC__
  typedef long long jlong;
#else
  typedef __int64 jlong;
#endif
調(diào)用

創(chuàng)建 HelloNativeTest 類以供測試:

public class HelloNativeTest {
    static {
        // 此處不需要 dll/so 后綴,系統(tǒng)會自動根據(jù)系統(tǒng)不同換后綴
        System.loadLibrary("HelloNative");
    }

    public static void main(String[] args){
        HelloNative.greeting();
    }
}

記住這里打印的消息是通過 printf 打印的,不是 java 的代碼打印的。

注:
一些本地代碼的共享庫必須先運(yùn)行初始化代碼,可以將初始化代碼放置到JNI_OnLoad方法中,如果提供該方法,則虛擬機(jī)關(guān)
閉時會調(diào)用JNI_OnUnload方法,原型如下:

  jint JNI_OnLoad(JavaVM* vm, void* reserved);    //返回它所需的虛擬機(jī)的最低版本,如JNI_VERSION_1_2
  void JNI_OnUnload(JavaVM* vm, void* reserved);

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/72634.html

相關(guān)文章

  • Andorid Studio NDK開發(fā)-Hello World

    摘要:介紹了在中配置的開發(fā)環(huán)境開發(fā)環(huán)境配置,開發(fā)環(huán)境配置完成之后,就要寫一下著名的程序了。尤其是但是并不妨礙你使用其他語言,只要調(diào)用約定支持就可以了。是指定所在的目錄,項(xiàng)目成功之后,會在目錄里生成文件。是包名加上類名。 介紹了在Android Studio中配置NDK的開發(fā)環(huán)境:Android Studio NDK開發(fā)-環(huán)境配置,NDK開發(fā)環(huán)境配置完成之后,就要寫一下著名的Hello Wor...

    melody_lql 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<