javacode:TestNative.java
package com.cloud;
import java.util.Date;
public class TestNative {
public static void main(String[] args) {
// test1_TestModifyField();
// test2_TestModifyField();
// test3_TestModifyField();
test4_TestCallMethod();
}
private static void test4_TestCallMethod() {
System.loadLibrary("NativeTestCodeDLL");
TestNative t = new TestNative();
t.sayHello();
}
private static void test1_TestModifyField() {
System.loadLibrary("NativeTestCodeDLL");
TestNative t = new TestNative();
t.sayHello();
}
private static void test2_TestModifyField() {
System.loadLibrary("NativeTestCodeDLL");
TestNative t = new TestNative();
t.sayHello();
}
private static void test3_TestModifyField() {
System.loadLibrary("NativeTestCodeDLL");
TestNative t = new TestNative();
t.sayHello();
System.out.println("c++修改後:number值="+t.number);
}
/**
* 1、第一個例子(native)
* 被native修飾,表示該方法無需實現,調用本地的c/c++代碼
* 編寫java程序,方法必須用native修飾,並且方法不可以有實現體。
* 調用【native>本地的】c/c++程序
*/
public native void sayHello();
/**
* 2、第二個例子
* c++中各種類的表示
*/
public int property = 10;
public int function(int foo,Date date,int[] arr)
{
System.out.println("function");
return 0;
}
public void showJava(int property)
{
System.out.println("This is showJava(int property);");
// TestNative.property = property;
// System.out.println("你好,Java"+property);
}
/**
* 3、第三個例子
* c++修改Java屬性。
*/
public int number = 10;
/**
* 4、第四個例子
* c++呼叫Java方法
* @return
*/
public double max(double num1,double num2)
{
System.out.println("max()");
return num1 > num2 ? num1 : num2;
}
}
c++ code sourceTest.cpp
#include"com_cloud_TestNative.h"
#include<iostream>
using namespace std;
JNIEXPORT void JNICALL Java_com_cloud_TestNative_sayHello(JNIEnv * env, jobject obj)
{
//第一個示例,用c++在控制檯輸出HelloWord。
/*
cout<<"Hello Word"<<endl;
*/
//第二個示例
//反向c++調用Java
/*
jclass clazz_TestNative = env->GetObjectClass(obj);
jfieldID fieldID_property = env->GetFieldID(clazz_TestNative,"property","I");
cout<<fieldID_property<<endl;
jmethodID jmethod_showJava = env->GetMethodID(clazz_TestNative,"showJava","(I)V");
jmethodID jmethod_function = env->GetMethodID(clazz_TestNative,"function","(ILjava/util/Date;[I)I");
*/
//第三個例子
//c++修改Java屬性
/*
jclass clazz_TestNative = env->GetObjectClass(obj);
jfieldID id_number = env->GetFieldID(clazz_TestNative,"number","I");
jint number = env->GetIntField(obj,id_number);
cout<<number<<endl;
env->SetIntField(obj,id_number,100L);
*/
//第四個例子
//c++調用Java方法
jclass clazz_TestNative = env->GetObjectClass(obj);
jmethodID id_max = env->GetMethodID(clazz_TestNative,"max","(DD)D");
jdouble maxReturnValue = env->CallDoubleMethod(obj,id_max,3.14,7.89);
cout<<maxReturnValue<<endl;
}
編寫Java程序通過jni調用c、c++程序
1 編寫java程序,編寫一個 聲明調用c++的實現方法,方法必須用native修飾,並且方法不可以有實現體。
2 用jdk自帶的javah命令,運行cmd命令行切換到class文件的目錄下,或者指定classpath
3 在cmd命令行輸入【javah java文件全類名】生成class文件所對應的c++頭文件【.h文件】 。class目錄下生成了.h的文件代表生成頭文件成功。
4 用c++的ide VS2010 創建c++項目》Win32》Win32控制檯應用程序》,輸入項目名稱,下一步》選擇DLL>選擇 空的工程。然後生成項目。
5 把剛纔javah命令生成的頭文件【.h】文件複製到c++工程下面,然後在VS裏選中:頭文件》鼠標右鍵》添加》現有項,選擇複製過來的頭文件【.h】。
6 選中:源文件》添加》新建項》c++文件(.cpp)。輸入文件名,創建文件。
7 打開復制進來的頭文件,複製方法到創建的.cpp文件裏。
8 編寫c++代碼
示例如下:
#include"com_cloud_TestNative.h"
#include<iostream>
using namespace std;
JNIEXPORT void JNICALL Java_com_cloud_TestNative_sayHello(JNIEnv * env, jobject obj)
{
cout<<"Hello Word"<<endl;
}
9 編譯。會發生錯誤。
第一個提示缺少jni.h文件,將jdk\include下面的jni.h文件拷貝到c++工程下,並且把<>括號修改爲雙引號,示例:#include "jni.h"
第二個提示缺少#include "jni_md.h",在jdk\include\win32裏找到jni_md.h,複製到c++工程下。
編譯通過。生成了c++項目的DLL文件。ok。
10 把dll動態鏈接庫路徑設置到環境變量Path中。
11 編寫Java程序調用DLL動態連接庫。java中用System.loadLibrary("TeatNative");DLL的文件名,不包含擴展名。加載TestNative.dll文件。
如果出錯,需要eclipse重啓,讓eclipse啓動的時候會重新加載環境變量
12 執行調用,輸出HelloWorld,成功!!!。
接下來,講解c++中調用Java程序
第三個參數簽名,通過javap -s -private/-p com.cloud.TestNative 命令生成。
1 靜態類對象獲取。
首先要通過env->FindClass("com/cloud/TestNative");來獲得類對象,用jclass 類型來接收。
例子:jclass clazz_TestNative = env->FindClass("com/cloud/TestNative");
非靜態類對象獲取。
通過env->GetObjectClass(obj);來獲取類對象。ojb參數爲生成的頭文件方法的第二個參數。
例子:jclass clazz_TestNative = env->GetObjectClass(obj);
2 方法對象獲取。
c++中通過env->GetMethodID(clazz_TestNative,"showJava","(I)V");方法來獲得類方法的對象,用jmethodID類型來接收。
例子:jmethodID id_func = env->GetMethodID(clazz_TestNative,"showJava","(I)V");
3 屬性對象獲取。
通過evn->GetFieldID(clazz_TestNative,"property","I");
例子:jfieldID fieldID_property = env->GetFieldID(clazz_TestNative,"property","I");