在我们Java开发中,有些时候会涉及到跨语言的调用,比如涉及到一些高效计算、图形渲染、加密和解密的时候会用到C++编写的程序,大部分情况我们都是利用JNI来调用C++的dll或者so,其实随着技术发展,更简单和易用的JNA应用而生。
JNI和JNA区别
JNI的使用
Java调用C++编写的.dll/.so文件,可以使用传统的JNI调用。
1.使用SUN规定的数据结构替代C语言的数据结构,调用已有的dll/so中公布的函数。
2.在Java中载入这个适配器dll/so,再编写JavaNative函数作为dll/so中函数的代理。
经过2个繁琐的步骤才能在Java中调用本地代码。
因此,很少有Java程序员愿意编写调用dll/.so库中的原生函数的java程序。这也使Java语言在客户端上乏善可陈。可以说JNI是Java的一大弱点!
如果你想具体了解JNI如何使用,可以参考这篇博客: https://blog.csdn.net/jiangwei0910410003/article/details/17465085
我相信你看了后,会有砸键盘的冲动。
其实正是因为JNI的复杂,所以有了更加简单易用的JNA。
JNI和JNA的区别
其区别主要有:
1.JNA为Java程序提供一种以纯Java编写调用本地共享类库的简便方法,不需要接触JNI或者本地代码。JNA功能同Windows的平台调用和Python中的ctypes相似。
2.JNA允许你使用Java方法调用来直接调用本地方法。JNA编写的Java方法调用接口看起来像本地接口。大多数调用不需要特殊处理和配置,不需要模板文件和代码生成。
3.JNA利用一小部分JNI库来实现动态调用本地方法。开发者使用一个Java接口来描述目标本地库的方法和结构。这使得利用本地代码的利用变得更为简单,并且不会带来多种配置和生成多个平台的JNI代码的开销。可以从这里找到技术细节。
4.JNA把性能、正确性和易用性当作首要目标。除此以外,JNA包含一个平台相关的类库,这个类库包含已经映射好的本地方法调用和许多便利本地方法调用的公用接口。
5.JNA是一个成熟的类库,被上百个商业软件和开源软件所使用。
使用:核心内容
首先推荐这个网站:https://www.eshayne.com/jnaex/index.html
上述网站可以找到C中结构 和 Java JNA中类的对应关系,可以借助查阅这个文档,实现类型映射构建对应实体类。
废话不多说我们先来一个代码解解渴:
假如有一个C的接口如下所示:
其编译后的文件为say.dll或者say.so
如果使用JNA需要先引入pom.
然后构建一个接口:
在使用的时候可以如下使用:
需要说明的是:
如果你不知道so或者dll 需要放在哪里,可以将其放在:src/main/resources理论上就可以成功调用了。
同时你也可以通过代码System.getProperty("java.library.path");输出的路径中选择任一路径来进行放置。
关于dll或者so文件存放路径可以参考:https://blog.csdn.net/daylight_1/article/details/70199452
总结
构建1个接口,在其中映射出正确的形参,参考地址再列出下:https://www.eshayne.com/jnaex/index.html
然后通过一个模板代码构建调用连接点:
通过接口中的连接点LIBRARY进行相应方法的调用。
其实JNA最难的一点是构建形参,特别是有指针、结构体等等包裹的时候,如果可能建议和C接口编写人沟通下,确定下,形参尽量简单。
作者:文敦复
链接:https://mp.weixin.qq.com/s/wDt9XjI3fpIZS1uET6BTLQ
来源:程序猿猩球
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。