天天看點

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

JNI簡介

JNI是Java Native Interface的縮寫,它提供了若幹的API實作了Java和其他語言的通信(主要是C&C++)。從Java1.1開始,JNI标準成為java平台的一部分,它允許Java代碼和其他語言寫的代碼進行互動。JNI一開始是為了本地已編譯語言,尤其是C和C++而設計的,但是它并不妨礙你使用其他程式設計語言,隻要調用約定受支援就可以了。使用java與本地已編譯的代碼互動,通常會喪失平台可移植性。但是,有些情況下這樣做是可以接受的,甚至是必須的。例如,使用一些舊的庫,與硬體、作業系統進行互動,或者為了提高程式的性能。JNI标準至少要保證本地代碼能工作在任何Java 虛拟機環境。

JNI的副作用

一旦使用JNI,JAVA程式就喪失了JAVA平台的兩個優點:

1、程式不再跨平台。要想跨平台,必須在不同的系統環境下重新編譯本地語言部分。

2、程式不再是絕對安全的,本地代碼的不當使用可能導緻整個程式崩潰。一個通用規則是,你應該讓本地方法集中在少數幾個類當中。這樣就降低了JAVA和C之間的耦合性。

什麼場合下應該使用JNI

當你開始着手準備一個使用JNI的項目時,請确認是否還有替代方案。應用程式使用JNI會帶來一些副作用。下面給出幾個方案,可以避免使用JNI的時候,達到與本地代碼進行互動的效果:

1、JAVA程式和本地程式使用TCP/IP或者IPC進行互動。

2、當用JAVA程式連接配接本地資料庫時,使用JDBC提供的API。

3、JAVA程式可以使用分布式對象技術,如JAVA IDL API。

這些方案的共同點是,JAVA和C處于不同的線程,或者不同的機器上。這樣,當本地程式崩潰時,不會影響到JAVA程式。

下面這些場合中,同一程序内JNI的使用無法避免:

1、程式當中用到了JAVA API不提供的特殊系統環境才會有的特征。而跨程序操作又不現實。

2、你可能想通路一些己有的本地庫,但又不想付出跨程序調用時的代價,如效率,記憶體,資料傳遞方面。

3、JAVA程式當中的一部分代碼對效率要求非常高,如算法計算,圖形渲染等。

總之,隻有當你必須在同一程序中調用本地代碼時,再使用JNI。

———————————————————以上内容來自百度百科—————————————————————

目的:

     通過學習JNI,進一步了解編譯過程。

     參考c程式的執行過程、Java代碼編譯和執行的整個過程

準備:

  • IDE準備

    Eclipse x64、JDKx64、vs2015。

    注釋:Eclipse與JDK必須一緻,也可以同為32位,對應生成32位的dll。

  • java環境變量設定(系統變量):

JAVA_HOME: jdk的安裝目錄

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

Path:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

CLASSPATH:.;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

操作:

step1:

編寫一個Java檔案(建立類的資訊),使用指令javah将該檔案編譯成.h頭檔案。

1.MyJNI.java

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:
public static void main(String[] he){
/*		System.loadLibrary("C++DLLtest");
		MyJNI m = new MyJNI();
		m.showThrone();*/
	}
}
           

2.javah生成.h檔案

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:
javah MyJNI
           

注釋:javah也可對.java檔案直接操作!本次應用,效果相同

3.修正

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

step2:

生成c++的dll檔案

1.建立源檔案

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:
詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:
詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:
詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:
詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:
// C++DLLtest.cpp : 定義 DLL 應用程式的導出函數。
//
#include "stdafx.h"
#include "jni.h" 
#include "C++DLLtest.h"
#include "MyJNI.h"
#include <iostream>
using namespace std;

JNIEXPORT void JNICALL Java_MyJNI_showThrone(JNIEnv *env, jobject obj)
{
	cout << "good job,Throne!" << endl;
}

           

注釋:函數定義請參考javah剛才生成的.h頭檔案中的函數聲明

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

2.添加外部依賴項

将jni.h 與 jni_md.h 添加到C++源檔案目錄

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:
詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

添加後:

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

注意:将jni.h中引用jni_md.h改為 #include “jni_md.h” ,友善程式查詢

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

3.生成.dll檔案

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

 注釋:若Eclipse與JDK都是32位的,則選擇x86

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

4.移動生成的.dll檔案到java項目下

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:
詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

     注釋:①可以把生成的dll檔案放在java項目根目錄下;

                 ②也可以将生成的dll所在路徑加入系統環境變量Path裡(不過要重新開機Eclipse)

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

                 ③當然也可以将該dll檔案放在Java的安裝目錄下的

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

或者

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

5.完善java代碼,運作觀察結果

詳細介紹,初試JNI(Eclipse+VS2015 x64),以及錯誤分析JNI簡介 目的:準備:操作: 實驗結果:

實驗結果:

     java調用C++編譯好的本地檔案,實作對應功能。

                                                                                                                           ——     by Throne in SICAU,2017.3.20

——————————————————The End ——————————————————

歡迎大家指正,共同進步!