Java通過JNI調用C++程序

JNI是Java Native Interface的縮寫,中文爲JAVA本地調用。使用JNI可以很方便的用我們的Java程序調用C/C++程序。很多時候,某些功能用Java無法實現,比如說涉及到底層驅動的一些功能,這時候我們就可以利用JNI來調用C或者C++程序來實現,這就是JNI的強大之處。但是JNI也有它的缺點,使用java與本地已編譯的代碼交互,通常會喪失平臺可移植性。

  下面是一個JNI例子,調用C++輸出"hello world":

 

第一步:創建Java類,在裏面定義一個本地方法(用native關鍵字修飾的方法)

  public native void sayHello();

第二步:使用javah命令(javah  類的全路徑)生成本地方法的C++頭文件

  在DOS窗口中進入工程所在目錄,然後執行javah com.test.TestNative命令,執行完之後就會在當前目錄生成一個後綴名爲.h的頭文件,如com_test_TestNative.h,這個頭文件是根據包名和類名來命名的。

複製代碼
 1 /* DO NOT EDIT THIS FILE - it is machine generated */
 2 #include <jni.h>
 3 /* Header for class com_test_TestNative */
 4 
 5 #ifndef _Included_com_test_TestNative
 6 #define _Included_com_test_TestNative
 7 #ifdef __cplusplus
 8 extern "C" {
 9 #endif
10 /*
11  * Class:     com_test_TestNative
12  * Method:    sayHello
13  * Signature: ()V
14  */
15 JNIEXPORT void JNICALL Java_com_test_TestNative_sayHello
16   (JNIEnv *, jobject);
17 
18 #ifdef __cplusplus
19 }
20 #endif
21 #endif
複製代碼

  15、16行是對TestNative類中的本地方法sayHello()的聲明。這個h文件相當於我們在java裏面的接口,這裏聲明瞭一個 Java_com_test_TestNative_sayHello (JNIEnv *, jobject);方法,然後在我們的本地方法裏面實現這個方法,也就是說我們在編寫C/C++程序的時候所使用的方法名必須和這裏的一致。

第三步:編寫C/C++本地代碼,生成動態鏈接庫文件

  首先在VC6.0(當然也可以用其他工具)中創建一個dll工程---Win32 Dynamic-Link Library工程。然後將上面生成的頭文件com_test_TestNative.h添加到該工程中,然後創建一個源文件引用該頭文件並且實現頭文件中本地函數的功能:

複製代碼
1     #include<iostream.h>
2     #include"com_test_TestNative.h"
3 
4     JNIEXPORT void JNICALL Java_com_test_TestNative_sayHello(JNIEnv *env, jobject obj)
5     {
6         cout<<"hello world!"<<endl;
7     }
複製代碼

 

  這裏因爲com_test_TestNative.h中引入了jni.h所以要將jni.h加入到VC6.0安裝目錄下的Include目錄中。jni.h在JDK安裝目錄下的include中,同時得件include/win32中的兩個頭文件jawt_md.h、jni_md.h也導入到VC6.0中。

  將所依賴的頭文件導入之後,我們就可以構建該工程了,按F7就行了,完了會在工程目錄中的Degug目錄下生成一個動態鏈接庫文件,我這裏生成的是NativeCode.dll。我們就可以將該dll文件拷貝到環境變量path所包含的目錄下給咱們的Java程序調用了,爲了方便,我們也可以將dll所在的工程目錄加入到環境變量path中去,這樣可以避免每次都要拷貝的麻煩。注意修改環境變量之後要重啓myeclipse。

 

第四步:Java調用本地函數

複製代碼
 1 package com.test;
 2 
 3 public class TestNative {
 4     public native void sayHello();
 5     
 6     /**
 7      * @param args
 8      */
 9     public static void main(String[] args) {
10         System.loadLibrary("NativeCode");
11         TestNative tNative = new TestNative();
12         tNative.sayHello();    
13     }
14 }
複製代碼

  第10行是加載動態鏈接庫,JVM只需要加載一次就可以調用了,“NativeCode”是上面生成的動態鏈接庫的名字,不含後綴名。

  運行該程序,成功打印輸出了"hello world"。

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