Java已經用了N年了,也知道它底層調用的是C/C++函數,也知道有JNI機制和native方法的存在。終於,昨天開始打算研究一下JNI,今天做了一個例子,這個例子是在Windows環境下運行一個具有native方法的java類。
1.建立一個InvokeNative.java檔案,編輯內容如下
package com.jni;public class InvokeNative { static { System.loadLibrary("invoke"); } public native void setAge(int age); public native static int getAge(); public static void main(String[] args) { InvokeNative invoke = new InvokeNative(); invoke.setAge(28); System.out.println(getAge()); }}
將InvokeNative.java編譯成java類檔案
javac com/jni/InvokeNative.java
2.根據InvokeNative.class產生JNI的標頭檔
javah -classpath . -jni com.jni.InvokeNative
上面語句要在com目錄的父目錄下執行,產生出com_jni_InvokeNative.h檔案,內容如下
3.寫C代碼並且產生動態串連庫檔案(動態串連庫檔案在linux下是.so為副檔名,在Windows下是.dll為副檔名)
產生.dll我使用的是VC6.0,當然你也可以用Visual Studio。如果沒有安裝,可以下載,我提供一個中文版的
http://www.cr173.com/soft/35179.html
在VC中建立一工程
看到下面介面,選擇工程-->Win32 Dynamic-Link Library,填寫工程名,點確定
選擇建立一個簡單的DLL 工程,點完成
將第2步產生的com_jni_InvokeNative.h標頭檔copy到F:\VSWORK\invoke目錄下
選擇左邊的FileView工作區,開啟StdAfx.h檔案
註:我寫錯了,把invoke寫成invoce了,大家用invoke就好了
在最下面添加下如代碼,並儲存
#include <jni.h>
#include "com_jni_InvokeNative.h"
開啟invoke.cpp檔案,在最下面添加如下實現代碼,並儲存
int i = 0;
JNIEXPORT void JNICALL Java_com_jni_InvokeNative_setAge (JNIEnv *, jclass, jint j)
{
i = j;
}
JNIEXPORT jint JNICALL Java_com_jni_InvokeNative_getAge (JNIEnv *, jclass)
{
return i;
}
如
在VC的菜單上選擇工具-->選項,開啟選項對話方塊。添加上jdk所在檔案夾下的include和include\win32檔案夾。如
我的%JAVA_HOME%是F:\software\jdk1.6
最後產生dll檔案,選擇組建-->全部重建。
執行成功如
將VC項目Debug檔案夾(我是F:\vswork\invoce\Debug)中的invoke.dll複製到C:\WINDOWS\system32目錄下
5.運行InvokeNative.class就會看到調用C/C++函數成功。
java com.jni.InvokeNative
列印資訊:
28
如果沒有將invoke.dll複製到C:\WINDOWS\system32目錄下,執行時需要指定java.library.path
java -Djava.library.path=./com/jni/ com.jni.InvokeNative