国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專(zhuān)欄INFORMATION COLUMN

java JNI簡(jiǎn)介

NicolasHe / 1414人閱讀

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

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

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

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

JNI 命名和native code書(shū)寫(xiě)分開(kāi),避免硬編碼

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

JAVA VM支持多線程,native 方法在編譯的時(shí)候需要加上對(duì)應(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”);  //名字可以隨便定義
     } 
} 

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

連接

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

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

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

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

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

方法簽名

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

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

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

JNI的Hello world實(shí)現(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實(shí)現(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:表示生成動(dòng)態(tài)鏈接庫(kù)
* -o:指定動(dòng)態(tài)鏈接庫(kù)編譯后生成的路徑以及文件名
* -framwork JavaVM -I:編譯JNI需要用到的JVM頭文件(jni.h)

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

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

java Str:paxi
hello paxi
附錄

JNI 文檔
JNI hello world原博客地址

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/71593.html

相關(guān)文章

  • 如何讀open jdk native 源碼

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

    Anchorer 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<