Java JNI学习(二)

本文介绍如何从C++代码调用Java属性,通过JNI实现跨语言交互。利用JNIEnv指针获取Java类属性,并修改其值。

今天继续记录JNI学习过程,今日内容为本地代码调用Java代码。

在刚开始的那篇中,我们在c++代码中输出了一句Hello JNI来开启JNI学习之旅,顺便从中也知道了在Java中用native方法可以调用C++中的代码。
其实今天所看到的也可以反过来用,在本地代码(也就是C++代码)中同样可以调用Java中的代码。
延续上一篇记录的笔记,我们通过javah工具生成的c++头文件中,会发现如下的函数声明:

JNIEXPORT void JNICALL Java_com_wang_TestNative_sayHello(JNIEnv* ,jobject)

这个声明中有两个参数需要传递,而这两个参数就和Java代码有关。具体来看c++源文件中的代码:

JNIEXPORT void JNICALL Java_com_wang_TestNative_sayHello(JNIEnv* env ,jobject obj){
      //.........
}

JNIEnv指针类型的参数实际上代表了Java环境。通过这个JNIEnv*指针,就可以对Java端的代码进行操作,如创建Java类的对象,调用Java的方法,获取Java对象的属性等等,有很大的作用。JNIEnv*有很多函数可以用,像:

NewObject/NewString/New<TYPE>Array;             //创建Java的对象用

Get/Set<TYPE>Field;                                               //获取或设置某一个对象的属性

Get/SetStatic<TYPE>Field;

Call<TYPE>Method/CallStatic<TYPE>Method等等很多函数。


jobject是一个指向java对象的引用,这个本地方法是非静态方法,因此这里代表了用了这个本地方法的java实例。


接下来看看jclass的取得:为了能够在C/C++中使用Java类。JNI.h头文件定义了jclass类型来表示Java中的Class类,可以通过下面函数取得:

jclass FindClass(const char* clsName);
jclass GetObjectClass(jobject obj);
jclass GetSuperClass(jclass obj);
另外在c++代码中访问Java端的代码,常见的就是获得类的属性和调用类方法,因此在头文件中会发现jfieldID和jmethodID两个来代表java端的属性和方法。

要访问java属性时要先取得Java属性的jfieldID,然后才能在本地代码访问java属性,同样的要先取得Java属性的jmethodID才能进行Java方法调用。

这下面首先来介绍获取属性的用法。。。

先在java代码中写一个属性:

public int number = 10;

因为是接着上次的那个工程,本有一个sayHello()方法,因此就在对于的c++中的Java_com_wang_TestNative_sayHello方法中来调用java中德number那个属性。

接下来就是在c++代码中书写了:

JNIEXPORT void JNICALL Java_com_wang_TestNative_sayHello
(JNIEnv *env, jobject obj){
	//cout<<"Hello JNI!"<<endl;
	jclass class_TestNative = env->GetObjectClass(obj);
	jfieldID id_number = env->GetFieldID(class_TestNative,"number","I");
	jint number = env->GetIntField(obj,id_number);

	cout<<number<<endl;

	env->SetIntField(obj,id_number,100L);
	
}

其中GetObjectClass(obj)就是获得TestNative类了,获得类后,就可以通过jfieldID获得number属性的id,GetFieldID中的“number”对应java中要获得的那个属性的名字,“I”对应的是属性的类型int。。然后再用GetIntField获得number属性的值。

SetIntField当然就是设置java中number属性值的方法了,这里将它设置为100.因为java中的int类型对应c++中的长整型类型,所以要写100L。

然后编译通过。

最后在java中的main函数里写上如下代码测试一下:

public static void main(String[] args) {
		// TODO Auto-generated method stub
		TestNative test = new TestNative();
		test.sayHello();
		System.out.println(test.number);
	}

这样就会发现最后的输出结果,第一个是10,第二个是100.

也就是第一个是用c++代码输出,证明取得了Java中的number属性,第二个是用java代码输出,是100,说明通过c++代码改变了number的值。



基于数据驱动的 Koopman 算子的递归神经网络模型线性化,用于纳米定位系统的预测控制研究(Matlab代码实现)内容概要:本文围绕“基于数据驱动的Koopman算子的递归神经网络模型线性化”展开,旨在研究纳米定位系统的预测控制问题,并提供完整的Matlab代码实现。文章结合数据驱动方法与Koopman算子理论,利用递归神经网络(RNN)对非线性系统进行建模与线性化处理,从而提升纳米级定位系统的精度与动态响应性能。该方法通过提取系统隐含动态特征,构建近似线性模型,便于后续模型预测控制(MPC)的设计与优化,适用于高精度自动化控制场景。文中还展示了相关实验验证与仿真结果,证明了该方法的有效性和先进性。; 适合人群:具备一定控制理论基础和Matlab编程能力,从事精密控制、智能制造、自动化或相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于纳米级精密定位系统(如原子力显微镜、半导体制造设备)中的高性能控制设计;②为非线性系统建模与线性化提供一种结合深度学习与现代控制理论的新思路;③帮助读者掌握Koopman算子、RNN建模与模型预测控制的综合应用。; 阅读建议:建议读者结合提供的Matlab代码逐段理解算法实现流程,重点关注数据预处理、RNN结构设计、Koopman观测矩阵构建及MPC控制器集成等关键环节,并可通过更换实际系统数据进行迁移验证,深化对方法泛化能力的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值