Java環境下的JNI調用

此文章寫於2015.02.03,發佈於網易博客,於2020.03.25遷移至此。

 

前言:記錄學習過程便於記憶。經過多次嘗試發現Java環境下的JNI調用與Andriod環境下的JNI調用有所不同,不知道是否正確。先記錄一下Java環境下的JNI調用。

參考文章:http://www.cnblogs.com/youxilua/archive/2011/09/16/2178554.html
開始使用JNI:

先寫一個Java文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.example.myjni; public class MyJni { //使用JNI的關鍵字native,決定我們那些方法能在我們的C文件中使用,只須聲明,不必實現
public native void display(); public native double sum(double x,double y); //用來讀取我們寫好的C語言編譯好的dll,後綴是系統自己辨認 static { System.loadLibrary("myjni"); } public static void main(String[] args) { new MyJni().display(); System.out.println(new MyJni().sum(2.0, 3.0)); } }

把寫好的類轉換成.class文件

javac com\example\myjni\MyJni.java

把.class文件轉換成頭文件,成功的話就會在src目錄下看到.h文件了

 javah com.example.myjni.MyJni

打開.h文件可以看到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_example_myjni_MyJni */ #ifndef _Included_com_example_myjni_MyJni #define _Included_com_example_myjni_MyJni #ifdef __cplusplus extern "C" { #endif /* * Class: com_example_myjni_MyJni * Method: display * Signature: ()V */ JNIEXPORT void JNICALL Java_com_example_myjni_MyJni_display (JNIEnv *, jobject); /* * Class: com_example_myjni_MyJni * Method: sum * Signature: (DD)D */ JNIEXPORT jdouble JNICALL Java_com_example_myjni_MyJni_sum (JNIEnv *, jobject, jdouble, jdouble); #ifdef __cplusplus } #endif #endif

native方法名稱組成詳解:

Java_爲前綴 + 類的全名標識(包名+類名) + “_” + 方法名

寫與.h文件對應的.c文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <jni.h> #include <stdio.h> #include "com_example_myjni_MyJni.h" JNIEXPORT void JNICALL Java_com_example_myjni_MyJni_display (JNIEnv *env, jobject obj) { printf("Hello MyJni!"); return; } JNIEXPORT jdouble JNICALL Java_com_example_myjni_MyJni_sum (JNIEnv *env, jobject obj, jdouble a, jdouble b) { return a + b; }

windows下編譯成dll文件,linux下編譯成so文件.這裏只講dll的,.so的以後嘗試了再說

首先查看我們的jdk文件夾,查看其include文件夾下是否存在Jni.h頭文件。在的話,繼續,否則重新安裝jdk。

使用mingw編譯.c文件(確保前面已經安裝了mingw)

gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -I"C:\Program Files\Java\jdk1.6.0_45\include" -I"C:\Program Files\Java\jdk1.6.0_45\include\win32" -shared myjni.c -o myjni.dll

命令 簡單介紹
-Wall -D_JNI_IMPLEMENTATION_ 把我們的C文件編譯成dll
-Wl,--kill-at   因爲mingw默認是用@來進行分隔,會導致JNI機制不能讀取,所以要刪掉.. 
mingw官網解釋
-I"C:\Program Files\Java\jdk1.6.0_45\include" -I"C:\Program Files\Java\jdk1.6.0_45\include\win32"  導入我們用的的jni需要的頭文件…盤符,文件夾自己修改
-shared -o 輸出配置,第一個參數爲我們輸出的名字(隨便起),第二個參數爲我們的C文件(隨便起)

沒出什麼提示的話就是成功的了…

運行我們的JNI(用eclipse的話,我們把編譯好的dll放到項目根目錄,注意不是代碼根目錄)

 

輸出結果

image

貌似java本身的輸出,優先級比較高?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章