Linux 下 JNA 调用动态连接库文件 so

简介: Linux 下 JNA 调用动态连接库文件 so

1. JNA

  • JNA介绍

JNA(Java Native Access )提供一组Java工具类用于在运行期动态访问系统本地库(native library:如Window的dll)而不需要编写任何Native/JNI代码。开发人员只要在一个java接口中描述目标native library的函数与结构,JNA将自动实现Java接口到native function的映射。

https://github.com/java-native-access/jna 
https://java-native-access.github.io/jna/5.3.0/javadoc/
  • 优点

JNA可以让你像调用一般java方法一样直接调用本地方法。就和直接执行本地方法差不多,而且调用本地方法还不用额外的其他处理或者配置什么的,也不需要多余的引用或者编码,使用很方便。

  • JNA描述

JNA类库使用一个很小的本地类库sub动态的调用本地代码。程序员只需要使用一个特定的java接口描述一下将要调用的本地代码的方法的结构和一些基本属性。这样就省了为了适配多个平台而大量的配置和编译代码。因为调用的都是JNA提供的公用jar 包中的接口。

  • 缺点

JNA是建立在JNI技术基础之上的一个Java类库,原来使用JNI,你必须手工用C写一个动态链接库,在C语言中映射Java的数据类型。JNA中,它提供了一个动态的C语言编写的转发器,可以自动实现Java和C的数据类型映射。你不再需要编写C动态链接库。当然,这也意味着,使用JNA技术比使用JNI技术调用动态链接库会有些微的性能损失。可能速度会降低几倍。但影响不大。

  • 关于jna-platform

其实很多情况下,jna.jar就完全满足一般项目开发的需要了,比如数据 类型的映射和常用的方法等等,这些C/C++中基础的映射已经可以实现,包括一些基本的平台方法,但是,真实涉及到比较深入的平台方法的时候,就需要platform.jar的帮助了,platform.jar是依赖于jna.jar实现的,包括了FileMonitor、FileUtils、KeyboardUtils、WindowUtil等Win32和平台相关的简化动态访问功能类中的大部分常用方法,为开发者开发自己的跨平台映射方法提供参考。

所以platform.jar对于jna.jar是一种补充和扩展,jna.jar相当于核,platfrorm.jar相当于增量插件。

2. JNA使用

  • pom.xml 引入
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.13.0</version>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna-platform</artifactId>
<version>5.13.0</version>
</dependency>

使用的函数必须与链接库中的函数原型保持一致,这是JNA甚至所有跨平台调用的难点,因为C/C++的类型与Java的类型是不一样的,必须转换成java对应类型让它们保持一致,这就是类型映射(Type Mappings),JNA官方给出的默认类型映射表如下:

其中类型映射的难点在于结构体、指针和函数回调。

  • 创建头文件 TestJna.h
#ifndef _TestJna_h
#define _TestJna_h
#ifdef __cplusplus
extern "C" {
#endif
int add(int a, int b);
int sub(int a, int b);
#ifdef __cplusplus
}
#endif
#endif
  • 创建头文件 TestJna.cpp
#include "TestJna.h"
extern "C" int add(int a, int b){
   return a+b;
}
extern "C" int sub(int a, int b){
  return a-b;
}

注意:一定要加extern "C"否则生成的方法名跟cpp文件定义的方法名不一致。

查看so方法名

nm -D libTestJnaEx.so | grep add
nm -D libTestJnaEx.so | grep sub
  • 生成动态连接库so文件
g++ TestJna.cpp -fPIC  -shared -o libTestJnaEx.so
  • 拷贝so文件到/usr/lib目录
cp libTestJnaEx.so /usr/lib
  • 创建TestJna.java文件
import com.sun.jna.Library;
import com.sun.jna.Native;
public class TestJnaEx {
  public interface CLibrary extends Library {
    CLibrary INSTANCE = (CLibrary) Native.load("TestJnaEx", CLibrary.class);
    int add(int a, int b);
    int sub(int a, int b);
  }
  public static void main(String[] args) {
    int sum = CLibrary.INSTANCE.add(2, 3);
    System.out.println(sum);
    int diff = CLibrary.INSTANCE.sub(5, 3);
    System.out.println(diff);
  }
}

导出可执行jar文件TestJnaEx.jar

  • 执行TestJnaEx.jar
java -jar TestJnaEx.jar

结果

师傅领进门,修行在个人。

参考
https://blog.csdn.net/y666666y/article/details/128303464
https://www.javacui.com/java/520.html
相关文章
|
4月前
|
监控 网络协议 Linux
在Linux中,如何查看某个网卡是否连接着交换机?
在Linux中,如何查看某个网卡是否连接着交换机?
|
2月前
|
Linux 网络安全
Linux虚拟机与主机和Xshell的连接问题解决
Linux虚拟机与主机和Xshell的连接问题解决
81 1
|
3月前
|
NoSQL Linux Redis
linux安装单机版redis详细步骤,及python连接redis案例
这篇文章提供了在Linux系统中安装单机版Redis的详细步骤,并展示了如何配置Redis为systemctl启动,以及使用Python连接Redis进行数据操作的案例。
75 2
|
3月前
|
Unix Linux 网络安全
python中连接linux好用的模块paramiko(附带案例)
该文章详细介绍了如何使用Python的Paramiko模块来连接Linux服务器,包括安装配置及通过密码或密钥进行身份验证的示例。
100 1
|
2月前
|
关系型数据库 MySQL Linux
Navicat 连接 Windows、Linux系统下的MySQL 各种错误,修改密码。
使用Navicat连接Windows和Linux系统下的MySQL时可能遇到的四种错误及其解决方法,包括错误代码2003、1045和2013,以及如何修改MySQL密码。
227 0
|
3月前
|
Linux Python
Linux之centos安装clinkhouse以及python如何连接
Linux之centos安装clinkhouse以及python如何连接
|
4月前
|
Ubuntu Linux 开发工具
【事件中心 Azure Event Hub】在Linux环境中(Ubuntu)安装Logstash的简易步骤及配置连接到Event Hub
【事件中心 Azure Event Hub】在Linux环境中(Ubuntu)安装Logstash的简易步骤及配置连接到Event Hub
|
4月前
|
移动开发 监控 网络协议
在Linux中,如何查看 http 的并发请求数与其 TCP 连接状态?
在Linux中,如何查看 http 的并发请求数与其 TCP 连接状态?
|
4月前
|
Ubuntu Linux 网络安全
在Linux中,如何配置VPN连接?
在Linux中,如何配置VPN连接?
|
4月前
|
缓存 负载均衡 网络协议
Linux的TCP连接数量与百万千万并发应对策略
【8月更文挑战第15天】在Linux系统中,关于TCP连接数量的一个常见误解是认为其最大不能超过65535个。这一数字实际上是TCP端口号的上限,而非TCP连接数的直接限制。实际上,Linux服务器能够处理的TCP连接数远远超过这一数字,关键在于理解TCP连接的标识方式、系统配置优化以及应用架构设计。
516 2