JNI的又一替代者—使用JNR访问Java外部函数接口(jnr-ffi)

本文介绍了JNR-FFI作为JNI的替代者,详细阐述了JNR-FFI的背景、优势,并展示了如何打包JNR-FFI的maven项目,包括通过Eclipse和maven命令行进行打包。此外,还给出了一个简单的JNR-FFI调用C函数的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. JNR简单介绍

继上文“JNI的替代者—使用JNA访问Java外部函数接口”,我们知道JNI越来越不受欢迎,JNI是编写Java本地方法以及将Java虚拟机嵌入本地应用程序的标准编程接口。它管理着JVM和非托管的本地环境之间的边界,提供数据编组和对象生命周期管理协议。

根据JEP(JDK增强提案) 191,JNI在下列几个方面最令开发人员痛苦:

  • 需要开发人员编写C代码,这意味着他们需要具备一个完全不同于Java的世界的专业知识。
  • 由于开发人员必须对JVM如何管理内存和代码多少有一些了解,所以典型的C和Java开发人员通常并不具备使用JNI所需的专业知识。
  • 开发人员必须能够为他们想要支持的每个平台构建代码,或者为终端用户提供适当的工具,由他们来完成这项工作。
  • 相比于相同的库绑定到本地应用程序,基于JNI的库性能通常较差。
  • JNI充当了一个不透明的安全边界。JDK并不知道库中的函数可能会调用什么,或者库中的代码是否会损害JVM的稳定或安全。
因此JNI创建本地函数的方式并不简单,于是产生了像 Java Native Access(JNA)和 Java Native Runtime(JNR)这样的库。JNA和JNR都是基于JNI创建的,而JEP 191定义的 Java Foreign Function Interface(FFI)可能会基于JNR。使用FFI API而不是JNI绑定本地代码和内存将成为开发人员更喜欢的方式。

FFI API将提供下列特性:

  • 一个描述本地库调用和本地内存结构的元数据系统。
  • 发现和加载本地库的机制。
  • 基于元数据将库/函数或内存结构绑定到Java端点的机制。
  • 用于Java数据类型和本地数据类型之间编组和解组的代码。
对Java FFI的需求已经产生了JNA和JNR库。JNA库应用更广泛(具体使用参见“ JNI的替代者—使用JNA访问Java外部函数接口”)。JNR库更全面,因为它实现了不同层次的抽象,提供了函数和内存元数据,对库和函数绑定进行了抽象。JNR已经在JRuby项目中大量使用,它可能会成为JEP 191的基础。

上面段落来自JEP 191的描述(由参考文献(1)翻译),由此可见虽然JNA使用广泛,但JNR可能更渐趋势,也许在不久的将来JNR-FFI(jffi)就会内建在JDK中与JNI一样成为Java访问外部函数的标准接口。因此,学习使用JNR是非常有必要的。

JNR-FFI项目也托管自Github,其使用方法与JNA差不多,不过JNR并没有给出相应的jar包,需要我们自己打包使用。


2. JNR项目打包(jnr-ffi.jar)——如何打包Github上的maven项目

首先要明确,Github上托管的项目一般是用maven管理构建的,而不是Eclipse/MyEclipse,因此如果你想通过从Github上直接下载项目源码(Download Zip的方式下载)然后导入或拷贝进Eclipse里打包是行不通的。我一开始也是这么做的,发现项目不完整,缺少一些包,因此打成的jar包也是不能用的。

让我惊讶的,在maven官方库里的jnr-ffi.jar包也是不完整的,下载下来也不能用,还有这个地方的所有jnr包,我都试过了,全部不完整,因此只能自己打包。

在打包之前,你首先需要将完整的源码下载下来,然后有两种方式打包成

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值