最近項目中混合編程,算法程序使用C/C++編寫,而算法服務器是Java開發的。爲便於開發整合,於是決定使用Java JNI來實現C/C++算法部分代碼的調用。於是也就有了這篇文章。本文以Windows系統上使用Java JNI混合編程爲例,Linux系統上同理(Linux系統上的動態鏈接庫爲.so後綴結尾)。
本文目錄
1、創建Java工程
1.1 新建Java工程
使用IDEA新建Java演示工程,過程如下:
(1)新建Java工程:
(2)直接跳過,next:
(3)填寫文件名和文件路徑,Finish,創建完成。
(4)工程新建完成如下:
1.2 編寫對應C/C++程序的Java對象類
(1)在src文件夾下創建jni包,新建類Demo.class,內容如下:
package jni;
public class Demo {
public native void sayHello(int x,int y);
}
(2)在終端Terminal中生成class類文件:
先進入到當前demo.java類所在文件夾下,使用以下命令生成class文件:
javac Demo.java
生成文件如下:
(3)使用javah生成h文件:
需要注意的是:在JDK10之後,javah命令已被移除,如果需要使用javah命令,可通過javac -h來實現。
這裏命令如下:
javac -h ./ Demo.java
這是可以看到生成的h頭文件如下:
h文件中內容如下:該文件自動生成,作文C++文件和Java文件的關聯。編譯製作dll動態鏈接庫需要用到,請勿修改。
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class jni_Demo */
#ifndef _Included_jni_Demo
#define _Included_jni_Demo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: jni_Demo
* Method: sayHello
* Signature: (II)V
*/
JNIEXPORT void JNICALL Java_jni_Demo_sayHello
(JNIEnv *, jobject, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
至此,Java對應的接口方面內容完成。
2、編譯製作dll動態庫
下面以VS來演示生成dll動態鏈接庫文件。
2.1 創建dll工程
(1)打開VS,新建項目:如下:選擇Win32項目:
(2)選擇DLL和空項目,如下:
(3)新建完成。
2.2 編寫C/C++源文件
(1)將上述1中生成的jni_Demo.h文件複製過來並添加進來,如下:
(2)編寫接口實現cpp文件:創建demo.cpp文件:並編寫代碼實現:
(3)配置包含目錄
在項目屬性-包含目錄中,添加Java JDK include文件,如下所示:
上面包含目錄,需要修改爲電腦上JDK安裝路徑中的include文件路徑。
(4)(非必選)配置dll對應的系統版本
需要注意的是,生成的dll動態鏈接庫,需要和系統位數對應,VS默認是32位的,如果服務器是64位的,需要手動修改平臺再生成。
如下圖所示,可以在配置管理器中,新建解決方案平臺爲X64的:
2.3 生成DLL動態鏈接庫文件
點擊生成,即可在Debug/Release中生成dll文件。示例如下:
3、Java程序調用
3.1 程序入口:
(1)新建程序入口類Mian類,並在其中編寫調用C++代碼的代碼,程序示例如下:
public class Main {
public static void main(String[] args){
System.load("F:\\StethoscopeProject\\JniDemo\\src\\native\\Win32Project2.dll");
Demo demo = new Demo();
demo.sayHello(2,3);
}
}
這裏首先加載了dll動態鏈接庫,後續通過調用demo對象的方法,即實現了C++代碼的調用。
(2)將前述2生成的dll動態鏈接庫文件放到程序的某路徑下,並修改load()中的文件路徑爲實際路徑。如下:
3.2 實驗結果
啓動程序,即可看到結果:這裏輸出爲:
可以看到,程序加載了C++的dll動態鏈接庫,Java應用可以正常調用C++實現。
至此2,實驗結束。
歡迎交流!