1.定義java類中的native方法,建立下面一個類
public class NativeDemo {
public static native void say(); //static的native方法
public native void sayHello(); //執行個體的native方法,兩者的處理不一樣
public static int number = 10;
int a = 2;
public void callThis(){
System.out.println("c++ call java method");
}
public static void main(String[] args) {
System.loadLibrary("NativeJni");
// NativeDemo.sayHello();
new NativeDemo().sayHello();
say();
}
}
2.進入java指令行
D:\project\workplatform.apps.demoLearnCenter\src\main\java>javah -help
用法:javah [選項] <類>
其中 [選項] 包括:
-help 輸出此幫助消息并退出
-classpath <路徑> 用于裝入類的路徑
-bootclasspath <路徑> 用于裝入引導類的路徑
-d <目錄> 輸出目錄
-o <檔案> 輸出檔案(隻能使用 -d 或 -o 中的一個)
-jni 生成 JNI樣式的頭檔案(預設)
-version 輸出版本資訊
-verbose 啟用詳細輸出
-force 始終寫入輸出檔案
使用全限定名稱指定 <類>(例
如,java.lang.Object)。
D:\project\workplatform.apps.demoLearnCenter\src\main\java>javap -help
Usage: javap <options> <classes>...
where options include:
-c Disassemble the code
-classpath <pathlist> Specify where to find user class files
-extdirs <dirs> Override location of installed extensions
-help Print this usage message
-J<flag> Pass <flag> directly to the runtime system
-l Print line number and local variable tables
-public Show only public classes and members
-protected Show protected/public classes and members
-package Show package/protected/public classes
and members (default)
-private Show all classes and members
-s Print internal type signatures
-bootclasspath <pathlist> Override location of class files loaded
by the bootstrap class loader
-verbose Print stack size, number of locals and args for methods
If verifying, print reasons for failure
3.在vc++建立一個dll的控制台工程
4.在vc的工程裡面導入剛才的那個NativeDemo.h的頭檔案,然後因為這個頭檔案需要引用jdk安裝目錄下的jni.h和jni_mt.h的兩個頭檔案,從jdk的安裝目錄下的拷貝到工程裡面
4.編寫NativeDemo.h的頭檔案定義的兩個類的實作(這裡需要吧jni.h include的時候要改為“”,而不是<>,因為jni.h是在目前工程裡面)
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class NativeDemo */
#ifndef _Included_NativeDemo
#define _Included_NativeDemo
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: NativeDemo
* Method: say
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_NativeDemo_say
(JNIEnv *, jclass);
/*
* Class: NativeDemo
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_NativeDemo_sayHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
c++源檔案
#include "NativeDemo.h"
#include "jni.h"
#include <iostream>
using namespace std;
JNIEXPORT void JNICALL Java_NativeDemo_say(JNIEnv * env, jclass jclazz) //static的方法生成的兩個參數是JNIEnv * env, jclass jclazz,第二個參數代表java的類的class執行個體
{
jclass jclass_native = env->FindClass("NativeDemo"); //查找類的class對象,
jfieldID jfield_numberId = env->GetStaticFieldID(jclass_native,"number", "I"); //獲得jclazz類的靜态字段number,第三個參數代表靜态變量的簽名,java每種類型對應到一個簽名串
jint jfield_number = env->GetStaticIntField(jclass_native, jfield_numberId);//獲得jclazz類的靜态變量的值
cout << jfield_number << endl; //列印靜态變量的值
}
JNIEXPORT void JNICALL Java_NativeDemo_sayHello(JNIEnv *env, jobject jobj)//執行個體方法生成的第二個參數是jobject,代表某一個執行個體
{
jclass clazz = env->GetObjectClass(jobj); //獲得執行個體jobj的class對象
jfieldID jfield_numberId = env->GetFieldID(clazz,"a", "I"); //獲得這個執行個體的a執行個體變量
jint jfield_value = env->GetIntField(jobj,jfield_numberId); //獲得這個執行個體的a執行個體變量的值
cout << jfield_value << endl;//列印這個執行個體的a執行個體變量的值
}
5.編譯這個vc的工程,生成一個dll檔案
6.在我的電腦屬性裡面設定環境變量path增加這個dll的目錄,因為java需要從path變量找到這個dll的目錄
7.打開eclipse,編寫調用的main函數代碼
public class NativeDemo {
public static native void say(); //static的native方法
public native void sayHello(); //執行個體的native方法,兩者的處理不一樣
public static int number = 10;
int a = 2;
public void callThis(){
System.out.println("c++ call java method");
}
public static void main(String[] args) {
System.loadLibrary("NativeJni");
// NativeDemo.sayHello();
new NativeDemo().sayHello();
say();
}
}
執行這個main函數,結果如下