Java小題,通過JNI調用本地C++共享庫中的對應方法實現楊輝三角的繪制
1.在Eclipse中配置Javah,配置如下
位置是你javah.exe在你電腦磁盤上的路徑
位置:C:\Program Files\Java\jdk1.8.0_112\bin\javah.exe
工作目錄:${project_loc}/src
自變量:-classpath .;./classes -d "${project_loc}/jni" -jni ${java_type_name}
2.創建一個java文件
1 package experience5; 2 3 public class NewNineToNine { 4 public native voidshowInfo(); 5 static{ 6 System.loadLibrary("sy5-1"); 7 } 8 public static void main(String[] args) { 9 // TODO Auto-generated method stub 10 NewNineToNine obj = new NewNineToNine(); 11 obj.showInfo(); 12 } 13 14 } 15
註意導入動態鏈接庫不需要加後綴名
將要用C++或C語言實現的方法設置成native類型
3.選擇要通過javah生成的類
(需要點擊一下吧,不然會報錯:Launching javah has encountered a problem.The selected resourse does not resolve to a Java element
或者Launching javah has encountered a problem.Variable references empty selection :${project_loc}
只要點擊了就好,個人覺得是這樣哇》。《)
然後點擊運行
這樣就會在工程文件夾裏生成一個jni的文件夾:
在jni包裏面生成了“experience5_NewNineToNine.h”
4.編寫一個C++文件,我用的是猥瑣死丟丟2013,選擇win32控制臺程序,創建一個空白的 dll動態鏈接庫
復制之前生成的“experience5_NewNineToNine.h“文件,
和C:\Program Files (x86)\Java\jdk1.8.0_151\include目錄下的jni.h文件
,以及C:\Program Files (x86)\Java\jdk1.8.0_151\include\win32目錄下的jni_md.h文件放到和test.cpp同目錄下
=======================
“experience5_NewNineToNine.h”文件:註意javah編譯出的頭文件打開之後顯示的是#include<jni.h>因為我們要引入jdk下的 jni.h文件,所以要用雙引號
/* DO NOT EDIT THIS FILE - it is machine generated */ #include "jni.h" /* Header for class experience5_NewNineToNine */ #ifndef _Included_experience5_NewNineToNine #define _Included_experience5_NewNineToNine #ifdef __cplusplus extern "C" { #endif /* * Class: experience5_NewNineToNine * Method: showInfo * Signature: () */ JNIEXPORT void JNICALL Java_experience5_NewNineToNine_showInfo (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
在源文件中創建一個test.cpp
JNIEXPORT void JNICALL Java_experience5_NewNineToNine_showInfo
(JNIEnv *, jobject);
就是在javah生成的頭文件中聲明的方法,我們需要在test.cpp中把這個方法實現
這些代碼沒優化,只到了能用的程度
test.cpp:
1 #include<iostream> 2 #include"experience5_NewNineToNine.h" 3 using namespace std; 4 JNIEXPORT void JNICALL Java_experience5_NewNineToNine_showInfo(JNIEnv *env, jobject obj) 5 { 6 int a[11][11]; 7 for (int i = 1; i <= 10; i++) { 8 a[i][1] = 1; 9 a[i][i] = 1; 10 for (int j = 2; j<i; j++) { 11 a[i][j] = a[i - 1][j - 1] + a[i - 1][j]; 12 } 13 14 if (i>1) { 15 for (int z = 0; z < (10 - i); z++) { 16 printf(" "); 17 18 } 19 for (int j = 1; j <= i; j++) { 20 cout << " " << a[i][j]; 21 } 22 } 23 else cout << " " << a[1][1] << endl; 24 25 cout << endl; 26 27 } 28 }
.要在java中輸出的內容就在test.cpp中的
JNIEXPORT void JNICALL Java_experience5_NewNineToNine_showInfo(JNIEnv *env, jobject obj)方法體中實現
然後直接編譯運行過,會提示不能運行.dll文件,那麽成功生成sy5-1.dll
==================
然後還沒完:
讓java程序成功調用sy5-1.dll有兩種方法,自然有一種比較煩
1.復制sy5-1.dll到系統的C:\Windows\System32目錄下,默認環境變量有這個
2.配置環境變量指向動態鏈接庫所在的路徑(這種表達我也不知道對不對,意思到了就好0.0)
配置好了就不用一次一次復制了,
==================
最後一步:
重啟eclipse,編譯運行。結果如下:
發生的問題:
1.拋出了java.lang.UnsatisfiedLinkError異常: no sy1 in java.library.path,程序沒找到.dll文件,放對位置就沒毛病了
2.can‘t load IA 32-bit .dll on a AMD 64-bit platform錯誤,參考網上回答,最後我用了一個32位的JDK然後妥了;
然後在StackOverflow裏有個回答:https://stackoverflow.com/questions/8113080/cant-load-ia-32-bit-dll-on-a-amd-64-bit-platform
裏面是用cmd編譯運行,有點迷,所以幹脆下個32位JDK一了百了
3.溜了溜了
Java小題,通過JNI調用本地C++共享庫中的對應方法實現楊輝三角的繪制