1. 程式人生 > >Java呼叫c++的方法

Java呼叫c++的方法

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部分


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());

	}

}
4、注意事項:

在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就可以了