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