jna enum 对应 java_JNA 实际开发中若干问题解决方法

本文介绍了使用JNA在实际开发中调用Windows DLL时遇到的问题及其解决方案,包括如何加载动态链接库、C类型与Java类型的映射,以及在映射中遇到的错误和解决办法,特别提到了枚举类型映射和错误处理策略。
摘要由CSDN通过智能技术生成

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

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

1. 调用 Windows 窗口打印Hello World

pom 依赖

net.java.dev.jna

jna

latest

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 类型映射。

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

Default Type Mappings 默认类型映射

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

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

char

8-bit integer

byte

BYTE, TCHAR

short

16-bit integer

short

WORD

wchar_t

16/32-bit character

char

TCHAR

int

32-bit integer

int

DWORD

int

boolean value

boolean

BOOL

long

32/64-bit integer

NativeLong

LONG

long long

64-bit integer

long

__int64

float

32-bit FP

float

double

64-bit FP

double

char*

C string

String

LPTCSTR

void*

pointer

Pointer

LPVOID, HANDLE, LPXXX

未签名类型作为签名类型来映射。 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

char

8-bit integer

byte

wchar_t

platform-dependent

char

short

16-bit integer

short

int

32-bit integer

int

int

boolean flag

boolean

enum

enumeration type

int (usually)

long long, __int64

64-bit integer

long

float

32-bit floating point

float

double

64-bit floating point

double

pointer (e.g. void*)

platform-dependent (32- or 64-bit pointer to memory)

pointer (e.g. void*),

array

32- 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 to Pointer before being passed to the native layer.

long

platform-dependent (32- or 64-bit integer)

const char*

NUL-terminated array (native encoding or jna.encoding)

const wchar_t*

NUL-terminated array (unicode)

char**

NULL-terminated array of C strings

wchar_t**

NULL-terminated array of wide C strings

void**

NULL-terminated array of pointers

struct*

struct

pointer to struct (argument or return) (or explicitly)

struct by value (member of struct) (or explicitly)

union

same as Structure

struct[]

array of structs, contiguous in memory

void (*FP)()

function pointer (Java or native)

pointer ( *)

same as Pointer

other

integer type

other

custom 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 出崩溃日志。

6. 参考

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值