亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

java JNI簡介

NicolasHe / 1477人閱讀

摘要:的接口函數(shù)和指針代碼想要訪問虛擬機(jī)需要調(diào)用方法,而獲取方法則通過。

JNI的接口函數(shù)和指針

native代碼想要訪問 java虛擬機(jī)需要調(diào)用JNI方法,而獲取JNI方法則通過 JNI interface Pointer。它實際指向的就是一個都是指針的數(shù)組,每個指針指向的都是一個接口函數(shù)

這樣做的優(yōu)勢:

JNI 命名和native code書寫分開,避免硬編碼

JNI interface Pointer 只在當(dāng)前線程有效,即native 方法不能在線程之間傳遞(不同線程的指針可能不一
樣),VM保證同一個線程中調(diào)用多次JNI interface Pointer是同一個
編譯

JAVA VM支持多線程,native 方法在編譯的時候需要加上對應(yīng)的參數(shù),如 gcc加上 -D_REENTRANT或者-D_POSIX_C_SOURCE

加載

代碼如下

package pkg;  

class Cls { 
     native double f(int i, String s); 
     static { 
         System.loadLibrary(“pkg_Cls”);  //名字可以隨便定義
     } 
} 

對于不同的系統(tǒng),打包的后綴名會有不同,solaris系統(tǒng)一般是libpkg_Cls.so(使用的時候則是直接用的pkg_Cls)Win32的系統(tǒng)則是pkg_Cls.dll

連接

如果當(dāng)前系統(tǒng)不支持動態(tài)連接,所有的Native方法必須預(yù)先和VM建立連接,通過System.loadLibrary是無法自動加載。如果要靜態(tài)連接可以使用 JNI的函數(shù) RegisterNatives

靜態(tài)連接需要把所有的library復(fù)制到可執(zhí)行的映像中;動態(tài)連接是把共享的library的名字放在一個可執(zhí)行的映像中,當(dāng)映像運(yùn)行的時候才去連接
Native方法名

生成規(guī)則:Java_ 作為前綴,類的全路徑名,用 “_” 分隔每一個目錄名,再加上 方法名,如果是重載的方法,則會添加 “__”和

方法簽名,比如: 全路徑是:com.study.jnilearn.HelloWorld,生成的方法是 Java_com_study_jnilearn_HelloWorld_sayHello:

查找規(guī)則:VM查找native library里面的方法名,首先查找短的名字,即方法名沒有參數(shù)簽名;然后查找有參數(shù)簽名的方法;長方法名只有在native方法重載了另一個native方法的時候需要

方法簽名

方法簽名的格式為:(形參參數(shù)類型列表)返回值。
形參參數(shù)列表中,引用類型以L開頭,后面緊跟類的全路徑名(需將.全部替換成/),以分號結(jié)尾

比如:long f(int n,String s,int[] arr);  對應(yīng)的Native方法簽名是   (ILjava/lang/String;[I)J.
各種類型簽名對比
Native的方法參數(shù)

第一個參數(shù)是JNI Interface pointer(類型是 JNIEnv),如果是靜態(tài)native方法,第二個參數(shù)則是對應(yīng)java class的引用,非靜態(tài)的native則對應(yīng)的是 對象的引用,其它的參數(shù)對應(yīng)的是java方法的參數(shù)

JNI的Hello world實現(xiàn)

創(chuàng)建自己的Hello world文件,在其中使用Native方法

public class HelloWorld {
    public static native String sayHello(String name);
    public static void main(String[] args) {
       String text = sayHello("paxi");
       System.out.println(text);
    }
    static{
        System.loadLibrary("HelloWorld");
    }
}

用javac編譯HelloWorld.java文件

用javah編譯產(chǎn)生頭文件 HelloWorld.h

命令為 javah -jni -d ./jni HelloWorld;-d:將生成的文件放到j(luò)ni目錄下
生成結(jié)果如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class HelloWorld */

#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     HelloWorld
 * Method:    sayHello
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_HelloWorld_sayHello
  (JNIEnv *, jclass, jstring);

#ifdef __cplusplus
}
#endif
#endif

用C實現(xiàn)HelloWorld.h中的函數(shù)

HelloWorld.c:
#include "HelloWorld.h"

#ifdef __cplusplus
extern "C" 
{
#endif

/*
 * Class:     HelloWorld
 * Method:    sayHello
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_HelloWorld_sayHello
  (JNIEnv *env, jclass cls, jstring j_str){
    const char *c_str = NULL;
    char buff[128] = {0};
    c_str = (*env)->GetStringUTFChars(env,j_str,NULL);
    if (c_str == NULL)
    {
        printf("out of memory
");
        return NULL;
    }
    printf("Java Str:%s
", c_str);
    sprintf(buff,"hello %s",c_str);
    (*env)->ReleaseStringUTFChars(env,j_str,c_str);
    return (*env)->NewStringUTF(env,buff);
  }
#ifdef __cplusplus
}
#endif

編譯C的代碼生成native文件

mac下命令為

gcc -dynamiclib -o extensions/libHelloWorld.jnilib jni/HelloWorld.c -framework JavaVM -I/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/include -I/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/include/darwin

* -dynamiclib:表示生成動態(tài)鏈接庫
* -o:指定動態(tài)鏈接庫編譯后生成的路徑以及文件名
* -framwork JavaVM -I:編譯JNI需要用到的JVM頭文件(jni.h)

執(zhí)行java程序,指定動態(tài)鏈接庫

命令為 java -Djava.library.path=動態(tài)鏈接的目錄 Helloworld

java Str:paxi
hello paxi
附錄

JNI 文檔
JNI hello world原博客地址

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

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

相關(guān)文章

  • 如何讀open jdk native 源碼

    摘要:它對應(yīng)的實現(xiàn)是在中,原始代碼為這里是省略的方法體轉(zhuǎn)換后這里是省略的方法體附錄簡介 怎么看open jdk native的源碼 類的命名與java類的命名是一模一樣的 方法的命名為JNI的代碼風(fēng)格 一般關(guān)注下文件頭,如果是系統(tǒng)文件,比如 , 是搜不到源碼的,否則全局可以搜到對應(yīng)的命名 JVM_ENTRY等類似這樣的字符是啥意思? JVM_ENTRY本身是一個宏定義,位于interfa...

    Anchorer 評論0 收藏0

發(fā)表評論

0條評論

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