JNA 实际开发中若干问题解决方法

简介: JNA 实际开发中若干问题解决方法

JNA 实际开发中若干问题解决方法

很早就已经听说过 JNI(Java Native Interface)Java 本地接口,奈何调用本地动态链接库太过于复杂,就一直没有再尝试。而最近因为工作需要调用 Windows DLL 动态链接库(对应 Linux 中 so 文件),而对 JNA 有了入坑体验,对实际工作中遇到的问题做出总结。

1. 调用 Windows 窗口打印Hello World

  1. pom 依赖
<dependency>
            <groupId>net.java.dev.jna</groupId>
            <artifactId>jna</artifactId>
            <version>latest</version>
        </dependency>
  1. JNA 在加载驱动时提供两种加载方式 , 直接映射接口生成

接口生成

public interface HelixcsDll extends StdCallLibrary {
   
        // loadLibary 为动态链接库加载目录
        HelixcsDll HELIXCS_DLL = Native.loadLibrary("helixcs.dll", HelixcsDll.class);
        // 在 dll 中存在相同 SomeFunction 的函数 
        void SomeFunction(String content);
    }

    // 调用
    HelixcsDll.HELIXCS_DLL.SomeFunction("Hello World");

直接映射

class Helixcs{
   
        static {
   
            Native.register("helixcs.dll");
        }
        // 映射为本地方法
        public static  native void SomeFunction(String content);

        public static void main(String[] args) {
   
            SomeFunction("Hello World");
        }
    }

2. C 类型和 Java 类型映射。

  1. JNA 官方提供的默认类型映射

Default Type Mappings 默认类型映射

Java primitive types (and their object equivalents) map directly to the native C type of the same size.

Java 原始类型以相同的大小映射 C 类型。


Native TypeSizeJava TypeCommon Windows Types
char8-bit integerbyteBYTE, TCHAR
short16-bit integershortWORD
wchar_t16/32-bit charactercharTCHAR
int32-bit integerintDWORD
intboolean valuebooleanBOOL
long32/64-bit integerNativeLongLONG
long long64-bit integerlong__int64
float32-bit FPfloat
double64-bit FPdouble
char C string String LPTCSTR
voidpointerPointerLPVOID, HANDLE, LP XXX

未签名类型作为签名类型来映射。 C 中枚举类型可替换为 “int”。

Unsigned types use the same mappings as signed types. C enums are usually interchangeable with "int".

3. 官方提供的详细的类型映射

Marshalling/Unmarshalling (Java/Native Type Conversions)



C Type Native Representation Java Type
char8-bit integerbyte
wchar_tplatform-dependentchar
short16-bit integershort
int32-bit integerint
intboolean flagboolean
enumenumeration typeint (usually)
long long, __int6464-bit integerlong
float32-bit floating pointfloat
double64-bit floating pointdouble
pointer (e.g. void ) platform-dependent (32- or 64-bit pointer to memory) Buffer


pointer (e.g. void),
array32- or 64-bit pointer to memory (argument/return)
contiguous memory (struct member)

[] (array of primitive type)


In addition to the above types, which are supported at the native layer, the JNA Java library automatically handles the following types. All but NativeMapped and NativeLong are converted tobefore being passed to the native layer.
longplatform-dependent (32- or 64-bit integer)
const char NUL-terminated array (native encoding or jna.encoding) String
const wchar_tNUL-terminated array (unicode)
char NULL-terminated array of C strings String[]
wchar_tNULL-terminated array of wide C strings
void * NULL-terminated array of pointers
struct
structpointer to struct (argument or return)
struct by value (member of struct) ()
unionsame as Structure
struct[]array of structs, contiguous in memory
void ( FP)() function pointer (Java or native)
pointer ( )same as Pointer
otherinteger type
othercustom mapping, depends on definition

4. 经验总结默认映射关系

尽管 JNA 官方已经提供了详细的类型映射文档。但在实际中发现按照官方映射可能出现莫名问题。对此我们在实际开发中对于一些类型的映射报错,可以参考以下映射做出调整。

C类型 JNA类型 说明
char * out Pointer Pointer room = new Memory(30);
uchar * out Pointer Pointer room = new Memory(30);
long * long [ ]
int * init [ ]
int int
char * byte [ ]
char * argv[] String []
uchar int
long NativeLong 兼容 32和64位

5. 常见错误

1. UnsatisfiedLinkError 问题

存在多个动态链接库之间调用情况,可能缺少其中某一个动态链接库文件。

2. Error Memory Access 问题

较大情况下存在参数类型映射错误,参考 JNA 类型映射。

3. dll can not find in win32/86

无法加载到动态链接库文件路径,需要将动态链接库放到项目根目录下,推荐开启 JNA 驱动加载 debug 模式,

System.setProperty("jna.debug_load", "true");

手动指定动态链接库文件路径

System.setProperty("jna.library.path",dllResourcePath);
System.setProperty("jna.platform.library.path",dllResourcePath);

4. 程序在运行一段时间后崩溃

在JNA crash-protection 中,官方文档说明的崩溃的主要原因,( These are often caused by improper mappings or invalid arguments passed to the native library.) 未知的参数类型映射导致vm崩溃。在很大程度上使用 Pointer 来作为 Java 通用映射类型。
而 JNA 默认程序保护Native.setProtected(true)使得 java 错误来代替程序崩溃,可以设置 Native.setProtected(false) 来 dump 出崩溃日志。

问题可以反馈到 JNA Google Group : https://groups.google.com/forum/#!forum/jna-users

6. 参考

  1. JNA Google Group : https://groups.google.com/forum/#!forum/jna-users

  2. JNA API Documentation: https://java-native-access.github.io/jna/4.2.1/overview-summary.html

  3. JNA VM Crashed Protection :http://java-native-access.github.io/jna/4.5.1/javadoc/overview-summary.html#crash-protection

目录
相关文章
|
Java 测试技术 C#
【开发者笔记】java 利用jna调用c#的dll
          一、需求阐述:   如果我们的项目利用c#开发,到了开发后期需要和java组进行合作,其中有一部分业务逻辑利用c#已经code completed,那么我们可能会考虑用java来调用现成的c#dll实现需求。
17675 0
|
6月前
|
弹性计算 固态存储 关系型数据库
国内高性价比云服务器选型指南:阿里云低价机型配置与市场对比
今年,阿里云针对不同用户群体推出多款高性价比云服务器产品,覆盖轻量应用服务器与 ECS 实例,价格区间从 38 元 / 年至 160 元 / 月,适配个人开发、中小企业轻量业务等多种场景,具体核心机型信息如下:
|
10月前
|
JSON 算法 API
小红书商品详情签名算法Python
本文分享了作者在电商开发中对接小红书商品详情API的实战经验,包括权限申请、签名算法、限流控制、数据解析及Webhook订阅等关键技术点,并提供了实用的Python代码示例。
|
机器学习/深度学习 编解码 人工智能
Kimi开源MoE架构多模态推理模型,小激活参数,大能量!
最近Moonshot AI推出了 Kimi-VL,这是一个高效的开源混合专家(MoE)视觉-语言模型(VLM),它提供了先进的多模态推理、长上下文理解以及强大的代理能力——所有这些功能都只需激活其语言解码器中的2.8B参数(Kimi-VL-A3B)。
1025 1
|
机器学习/深度学习 弹性计算 缓存
简单聊聊,阿里云2核2G3M带宽云服务器与轻量应用服务器区别及选择参考
2核2G3M带宽云服务器与轻量应用服务器是目前阿里云的活动中,入门级走量型云服务器,轻量云服务器2核2G3M带宽68元一年,经济型e实例云服务器2核2G3M带宽99元1年。同样的配置,对于有的新手用户来说,有必要了解一下他们之间的区别,以及各自的购买和续费相关政策,从而选择更适合自己需求的云服务器。本文为大家简单分析一下我们应该选择哪一款。
|
安全 Java C#
Unity多线程使用(线程池)
在C#中使用线程池需引用`System.Threading`。创建单个线程时,务必在Unity程序停止前关闭线程(如使用`Thread.Abort()`),否则可能导致崩溃。示例代码展示了如何创建和管理线程,确保在线程中执行任务并在主线程中处理结果。完整代码包括线程池队列、主线程检查及线程安全的操作队列管理,确保多线程操作的稳定性和安全性。
|
机器学习/深度学习 PyTorch 测试技术
PyTorch实战:图像分类任务的实现与优化
【4月更文挑战第17天】本文介绍了使用PyTorch实现图像分类任务的步骤,包括数据集准备(如使用CIFAR-10数据集)、构建简单的CNN模型、训练与优化模型以及测试模型性能。在训练过程中,使用了交叉熵损失和SGD优化器。此外,文章还讨论了提升模型性能的策略,如调整模型结构、数据增强、正则化和利用预训练模型。通过本文,读者可掌握基础的PyTorch图像分类实践。
|
分布式计算 资源调度 Hadoop
Apache Hadoop入门指南:搭建分布式大数据处理平台
【4月更文挑战第6天】本文介绍了Apache Hadoop在大数据处理中的关键作用,并引导初学者了解Hadoop的基本概念、核心组件(HDFS、YARN、MapReduce)及如何搭建分布式环境。通过配置Hadoop、格式化HDFS、启动服务和验证环境,学习者可掌握基本操作。此外,文章还提及了开发MapReduce程序、学习Hadoop生态系统和性能调优的重要性,旨在为读者提供Hadoop入门指导,助其踏入大数据处理的旅程。
1507 0