2Java程序JNI调用C++之四步骤

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

 

 

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