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

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目录 I. 目录 1 II. java c/cpp互相调用实例(姊妹篇之一)——java调用c/cpp 4 一 先制作一个系统中有的DLL文件(cpp给出的sdk接口) 4 二 JNI 7 1、 编写java文件 7 2、 生成.h头文件 8 3、 用c/cpp实现这个头文件 9 三 测试 10 四 最后补充 11 III. java c/cpp互相调用实例(姊妹篇之二)——c/cpp调用java 11 一、 编写java代码 12 二、 编译java代码 12 三、 编写 C/C++ 代码 13 四、 运行exe 18 IV. Java JNI 编程进阶 18 一、 解决性能问题 18 二、 解决本机平台接口调用问题 19 三、 嵌入式开发应用(JNI小例子) 20 1、 新增一个基础类 22 2、 定义新类继承基础类 23 3、 编写调用类 23 4、 新增两个本地方法 24 5、 修改 RunMain 类 25 6、 新增一个方法处理java对象 26 7、 新增一个方法处理数组 29 8、 改写RunMain 32 四、 参考资料: 33 V. Eclipse+CDT+MinGW 进行JAVA调用C/C++ 34 一、 安装eclipse3.2。 34 二、 安装MinGW。 34 1、 下载MinGW 34 2、 安装 34 3、 安装版本 34 4、 选择安装的编译器 34 5、 选择安装路径,下一步 35 6、 等待下载软件 35 三、 MinGW的环境变量设置 35 1、 设置Path 35 2、 设置C_INCLUDE_PATH 35 3、 设置CPLUS_INCLUDE_PATH 35 四、 做一个小技巧修改 35 五、 安装CDT插件 36 1、 下载CDT插件 36 2、 安装CDT插件 36 六、 简单介绍CDT的使用吧 36 1、 新建一个C++项目 36 2、 输入New Project名字 36 3、 给项目新建一个的源文件 36 4、 接着出现文件添加的窗口,在File Name栏里面写上文件名 36 5、 编辑hello.cpp 37 6、 添加一个编译命令 37 七、 让我们开始进入真正的工作吧! 38 The Java side 38 1、 建立Java工程JavaHello,编写java类 38 2、 用命令生成头文件 38 The C side-Compiling the Library 40 1、 建立标准C工程Cpro,并生成dll文件 40 1) 将生成的头文件test_Hello.h拷贝到C工程Cpro下 40 2) 编写C类Hello.c,内容为: 40 3) 在C工程Cpro下建立hello.def文件(用于定义导出的函数),内容为: 40 4) 在C工程Cpro下建立makefile文件,内容为: 40 5) Make Targets 40 6) Make Targets视图下双击step1,在C工程Cpro下生成hello.o 文件。 41 7) Make Targets视图下双击step1,在C工程Cpro下生成hello.dll 文件。 41 2、 JAVA调用DLL 41 1) 将hello.dll拷贝到Java工程JavaHello下。 41 2) 运行Hello.java,则可以看到输出结果: 41 1) 将Hello.c改为Hello.cpp 41 2) 将makefile内容改为: 41 3) 其他的几乎都不用改变也可以。 42 评论: 42 VI. c++如何调用java程序 51 DemoMain.java内容如: 51 采用vc6++ IDE,采用JNI技术实现。 51 1、 编译时 51 2、 运行时 51 程序的关键在 53 VII. JNI 53 一、 定义 53 二、 设计目的 54 三、 书写步骤 54 1) 编写java程序:这里以HelloWorld为例。 54 2) 编译 55 3) 生成扩展名为h的头文件 55 4) 编写本地方法实现和由javah命令生成的头文件里面声明的方法名相同的方法。 56 5) 生成动态库 56 6) 运行程序 java HelloWorld就ok. 56 四、 调用中考虑的问题 56 1) java和c是如何互通的? 57 2) 如何将java传入的String参数转换为c的char*,然后使用? 57 3) 将c中获取的一个char*的buffer传递给java? 57 4) 不知道占用多少空间的buffer,如何传递出去呢? 58 五、 对JAVA传入数据的处理 58 1) 如果传入的是bytearray的话,作如下处理得到buffer: 58 VIII. C/C++调用JAVA类 58 一、 加载虚拟机: 59 二、 获取指定对象的类定义: 59 三、 获取要调用的方法: 59 四、 调用JAVA类方法: 60 五、 获得类属性的定义: 60 六、 数组处理: 60 七、 异常: 60 八、 多线程调用 61 Java代码 61 命令行运行:javap -s -p MyTest ,输出: 62 C代码testjava.c: 62 编译: 65 运行结果: 65

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值