(译)Simple JNI on Ubuntu 9.04

本文通过两个具体实例介绍如何在Java中使用JNI(Java Native Interface)调用C++代码,包括从Java传递字符串到本地方法并打印,以及通过JNI处理异常。

人们可以找到很多关于Solaris和Windows中JNI的教程,而且在那些例子中C++出现得也不是那么频繁,出于这个原因,我通过两个例子来说明一下其使用。

对于下面的程序,要求你使用的SunJDK,而不是OpenJDK(在文章后面我会再次提到这点)。

第一个例子是从Java中传递一个字符串到native method中,在native method中打印个性化的Helllo World。

public class HelloWorld {
	public native void sayHi(String name);

	static {
		System.loadLibrary("nativehw");
	}

	public static void main(String[] args) {
		HelloWorld h = new HelloWorld();
		h.sayHi("Night Rider");
	}
}

 

在这里先说明一下,我们打算通过nativehw库来调用本地方法sayHi。

编译的我们类:

javac HelloWorld.java 

 

然后生成本地方法的头文件:

javah -jni HelloWorld

 

接着实现HelloWorld.h声明的方法:

(注,注意第一行的include。原文中这段代码不是很完整,为保持作者原意,故此这里我也不做相关修改)

#include 
#include "HelloWorld.h"

using namespace std;

JNIEXPORT void JNICALL Java_HelloWorld_sayHi(JNIEnv *env, jobject o, jstring s)
{
	const char *str = env->GetStringUTFChars(s, 0); cout << "Hello " << str << endl;
	env->ReleaseStringUTFChars(s, str); 
}

 

由于在C++中没有像Java那样的垃圾收集器,所以我们需要做一些清理工作。(译者注:这个是作者的建议,在本段代码中并未体现出来)

 

写好后保存为HelloWorld.cpp然后进行编译:

g++ -shared -I/usr/lib/j2sdk1.6-sun/include -I/usr/lib/j2sdk1.6-sun/include/linux HelloWorld.cpp -o libnativehw.so 

 

注意不同系统环境的include目录的路径可能会有所不同,生成前面提到的nativehw库。

我们像这样运行的例子:

java -Djava.library.path=. HelloWorld

 预期的输出结果是“Hello Night Rider”。

 

 

 

第二个例子将展示用JNI处理一些异常,同样我们先开始编写Java代码:

public class MoreStuff {
	public native double div(double x, double y) throws Exception;

	static {
		System.loadLibrary("whatever");
	}

	public static void main(String[] args) {
		MoreStuff m = new MoreStuff();
		try {
			System.out.println("7.0 / 2.0 = " + m.div(7.0, 2.0));
			System.out.println("0.0 / 0.0 = " + m.div(0.0, 0.0));
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
}

 

 编译并且生成头文件:

javac MoreStuff.java
javah -jni MoreStuff

 

实现的声明的发发的C++代码如下:

NIEXPORT jdouble JNICALL Java_MoreStuff_div (JNIEnv *env, jobject o, jdouble x, jdouble y)
{
	if(0.0 == y){
		jclass e = env->FindClass("java/lang/IllegalArgumentException");
		if (e == 0) {
			return -3.14;
		}
		env->ThrowNew(e,"Zero argument exception.");
		env->DeleteLocalRef(e);
	}
	return x/y;
}

 

 建议使用更健壮的异常处理机制来处理异常(译者注:这也是作者的建议,并未在代码中体现出来)。

 

 

g++ -shared -I/usr/lib/j2sdk1.6-sun/include -I/usr/lib/j2sdk1.6-sun/include/linux MoreStuff.cpp -o libwhatever.so

 

 这里是执行的操作和输出的结果:

java -Djava.library.path=.
MoreStuff 7.0 / 2.0 = 3.5
Zero argument exception.

 

为了让编译通过,可能需要编辑JDKHOME/include/jni.h,包括相关文件或目录(译者注:此即为上文中为何没有在代码中包含这个的原因):

#include "jni_md.h"

 或着这样:

#include "linux/jni_md.h"

 

(译者:这里我认为作者的意思是应该是运行Java例子时使之包括相关的路径,尤其要注意jni.h和jni.md.h,这两个头文件一定不能漏掉。建议在g++中添加-I标志来特别标明这几个include路径)。

这里是我安装的JDK路径的描述,虽然jni.h也是OpenJDK源码的一部分,但是我却没有在Ubuntu8.04的OpenJDK安装路径中找到它,所以这也是我强调使用SunJDK的原因。

基于数据驱动的 Koopman 算子的递归神经网络模型线性化,用于纳米定位系统的预测控制研究(Matlab代码实现)内容概要:本文围绕“基于数据驱动的Koopman算子的递归神经网络模型线性化”展开,旨在研究纳米定位系统的预测控制方法。通过结合数据驱动技术与Koopman算子理论,将非线性系统动态近似为高维线性系统,进而利用递归神经网络(RNN)建模并实现系统行为的精确预测。文中详细阐述了模型构建流程、线性化策略及在预测控制中的集成应用,并提供了完整的Matlab代码实现,便于科研人员复现实验、优化算法并拓展至其他精密控制系统。该方法有效提升了纳米级定位系统的控制精度与动态响应性能。; 适合人群:具备自动控制、机器学习或信号处理背景,熟悉Matlab编程,从事精密仪器控制、智能制造或先进控制算法研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①实现非线性动态系统的数据驱动线性化建模;②提升纳米定位平台的轨迹跟踪与预测控制性能;③为高精度控制系统提供可复现的Koopman-RNN融合解决方案; 阅读建议:建议结合Matlab代码逐段理解算法实现细节,重点关注Koopman观测矩阵构造、RNN训练流程与模型预测控制器(MPC)的集成方式,鼓励在实际硬件平台上验证并调整参数以适应具体应用场景。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值