1. 程式人生 > >Java小題,通過JNI調用本地C++共享庫中的對應方法實現楊輝三角的繪制

Java小題,通過JNI調用本地C++共享庫中的對應方法實現楊輝三角的繪制

question 文件夾 path ron variable iostream ring printf spl

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 void
showInfo(); 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++共享庫中的對應方法實現楊輝三角的繪制