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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java native 例子_Java native方法以及JNI实践

發布時間:2024/4/20 java 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java native 例子_Java native方法以及JNI实践 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

今天看AndFix實現時,核心方法之ReplaceMethod方法是一個native方法,之前并沒有遇到過,所以在此整理記錄。

native的作用

總而言之:native是與C++聯合開發的時候用的!使用native關鍵字說明這個方法是原生函數,也就是這個方法是用C/C++語言實現的,并且被編譯成了DLL,由java去調用。

native 是用做java 和其他語言(如c++)進行協作時使用的,也就是native 后的函數的實現不是用java寫的。

既然都不是java,那就別管它的源代碼了,我們只需要知道這個方法已經被實現即可。

native的意思就是通知操作系統, 這個函數你必須給我實現,因為我要使用。 所以native關鍵字的函數都是操作系統實現的, java只能調用。

java是跨平臺的語言,既然是跨了平臺,所付出的代價就是犧牲一些對底層的控制,而java要實現對底層的控制,就需要一些其他語言的幫助,這個就是native的作用了

JNI簡介

native方法是通過java中的JNI實現的。JNI是Java Native Interface的 縮寫。從Java 1.1開始,Java Native Interface (JNI)標準成為java平臺的一部分,它允許Java代碼和其他語言寫的代碼進行交互。

JNI一開始是為了本地已編譯語言,尤其是C和C++而設計 的,但是它并不妨礙你使用其他語言,只要調用約定受支持就可以了。

目前java與dll交互的技術主要有3種:jni,jawin和jacob。

目前功能性而言:jni >> jawin > jacob,其大致的結構如下圖:

jni_jawin_jacob

windows,基于native的PE結構,windows的jvm基于native結構,Java的應用體系構建于jvm之上。jvm通過加載此jni程序間接調用目標原生函數。

image

JNI的生成步驟——Mac版

編寫帶有native聲明的方法的java類,生成.java文件

使用javac命令編譯所編寫的java類,生成.class文件

使用javah -jni java類名生成擴展名為h的頭文件,也即生成.h文件

使用C/C++(或者其他編程想語言)實現本地方法,創建.h文件的實現,也就是創建.cpp文件實現.h文件中的方法

將C/C++編寫的文件生成動態連接庫,生成jnilib文件

JNI實例

接下來我們按照上述步驟一個一個來生成JNI實例

1.編寫帶有native聲明的java類,HelloWorld.java

public class HelloWorld {

public native void sayHelloWorld(); //申明一個native方法

static{

System.loadLibrary("HelloWorldImpl"); //裝入動態鏈接庫,"HelloWorldImpl"是裝入動態鏈接庫的名稱

}

public static void main(String[] args){

HelloWorld helloWorld = new HelloWorld();

helloWorld.sayHelloWorld();

}

}

2.使用javac生成HelloWorld.class

javac HelloWorld.java

3.使用javah -jni java類生成擴展名為h的頭文件

javah -jni HelloWorld

此處需要注意的是,我們應該在包名的根目錄下執行,因為生成的文件的文件名需要引用包目錄。不然就會報找不到類文件的錯誤

生成com_think_jni_HelloWorld.h文件

/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for class com_think_jni_HelloWorld */

#ifndef _Included_com_think_jni_HelloWorld

#define _Included_com_think_jni_HelloWorld

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: com_think_jni_HelloWorld

* Method: displayHelloWorld

* Signature: ()V

*/

JNIEXPORT void JNICALL Java_com_think_jni_HelloWorld_displayHelloWorld

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

這里我們可以這樣理解:這個h文件相當于我們在java里面的接口,這里聲明了一個 Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);方法,然后在我們的本地方法里面實現這個方法,也就是說我們在編寫C/C++程序的時候所使用的方法名必須和這里的一致

4使用C/C++實現本地方法

創建HelloWorldImpl.cpp,代碼如下所示:

#include "jni.h"

#include "com_think_jni_HelloWorld.h"

#include

JNIEXPORT void JNICALL Java_com_think_jni_HelloWorld_displayHelloWorld(JNIEnv *env,jobject obj){

printf("Hello World!\n");

return;

}

5 將本地方法編寫的文件生成動態鏈接庫

gcc -I/Library/Java/JavaVirtualMachines/[根據裝的jdk版本來定]/Contents/Home/include/ -dynamiclib HelloWorldImpl.cpp -o libhell.jnilib

但是會出現運行這個命令報錯

file not found

我們找到這個文件在

/Library/Java/JavaVirtualMachines/[根據安裝的jdk版本來定]/Contents/Home/include/darwin/

這個目錄下,所以我們再鏈接該目錄到以上命令中

gcc -I/Library/Java/JavaVirtualMachines/jdk1.8.0_71.jdk/Contents/Home/include/ -I/Library/Java/JavaVirtualMachines/jdk1.8.0_71

.jdk/Contents/Home/include/darwin/ -dynamiclib HelloWorldImpl.cpp -o libhell.jnilib

最終成功生成libhell.jnilib

6 運行可執行文件

把上述文件放在同一個文件夾后,執行

java HelloWorld

即可看到

image

總結

以上是生活随笔為你收集整理的java native 例子_Java native方法以及JNI实践的全部內容,希望文章能夠幫你解決所遇到的問題。

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