Java呼叫c++的方法
阿新 • • 發佈:2019-02-19
1、Java呼叫c++是通過jni來實現的
2、通常Java作為整個程式的框架,然後具體的函式使用c++來實現,將c++寫的程式碼編譯成動態庫,然後Java在程式碼中呼叫這些動態庫!
3、下面是一個例子:
c++部分,標頭檔案
// BeCall.h : BeCall DLL 的主標頭檔案 // #ifndef _BE_CALL_H_ #define _BE_CALL_H_ // 包含相應的標頭檔案 #ifdef WIN32 #include "jni.h" #else #include </usr/lib/jvm/jdk/include/linux/jni_md.h> #include </usr/lib/jvm/jdk/include/jni.h> #endif #ifdef __cplusplus extern "C" { #endif // 定義一個函式 JNIEXPORT jint JNICALL Java_TestCall_get(JNIEnv *, jclass); // 定義一個函式 JNIEXPORT void JNICALL Java_TestCall_set(JNIEnv *, jclass, jint); #ifdef __cplusplus } #endif #endif
c++部分,原始檔
// BeCall.cpp : 定義 DLL 的初始化例程。 #ifdef WIN32 #include "stdafx.h" #else #endif #include "BeCall.h" int i = 0; // 函式的實現 JNIEXPORT jint JNICALL Java_TestCall_get (JNIEnv *, jclass) { return i; } // 函式的實現 JNIEXPORT void JNICALL Java_TestCall_set (JNIEnv *, jclass, jint j) { i = j; }
Java部分
4、注意事項:public class TestCall { static { //System.out.print(System.getProperty("java.library.path")); System.setProperty("java.library.path","."); System.loadLibrary("BeCall"); } public native static int get(); public native static void set(int i); /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub TestCall testCall = new TestCall(); testCall.set(10); System.out.print(testCall.get()); } }
在c++中定義的函式,例如:
Java_TestCall_set
必須要按照下面的方式命名:Java+Java類名+函式名,在上面例子中,Java類名是TestCall,Java的函式名是set,因此,函式名是
Java_TestCall_set
5、編譯Java程式碼:javac TestCall.java 會生成一個TestCall.class的檔案
6、windows下編譯和呼叫動態庫
直接使用vs進行編譯即可,很方便,編譯出來的結果是BeCall.dll
把BeCall.dll放到TestCall.class檔案所在的目錄下
直接使用 java TestCall 命令即可執行
7、Linux下編譯和呼叫動態庫
使用命令 g++ -fPIC -shared -o libBeCall.so BeCall.cpp 即可生成 動態庫 libBeCall.so
此時如果直接執行 java TestCall 會出錯,如下:
java.lang.UnsatisfiedLinkError: no BeCall in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1886)
這是因為找不到動態庫所在的目錄導致的,可以把動態庫複製到/lib目錄下:sudo cp libBeCall.so /lib/libBeCall.so
此時執行 TestCall就可以了