JNA支持的JAVA和本地代码之间的映射关系
Native Type Size Java Language Type Common Windows Types
char 8-bit integer byte BYTE, TCHAR
short 16-bit short short WORD
wchar_t 16/32-bit character char WCHAR, TCHAR
int 32-bit integer int DWORD
int boolean value boolean BOOL
long 32/64-bit integer NativeLong LONG
long long, __int64 64-bit integer long
float 32-bit FP float
double 64-bit FP double
char* C string String LPTCSTR
void* pointer Pointer LPVOID, HANDLE, LPXXX
使用JNA替代JNI调用本地方法
JNA全称是Java Native Access,是Sun推出的一种调用本地方法技术,比起它的同门师兄JNI,JNA大大简化了调用本地方法的过程,使用也比较方便, JNA是在JNI的基础上完善的,用青出于蓝而胜于蓝来形容一点不为过,下面看一下JNI的调用过程:
使用JNI你得完成上面这些步骤,比较麻烦,而是用JNA就省事多了,基本上不需要脱离Java环境就可以完成。
JNA项目主页是https://jna.dev.java.net/, 目前最新的版本是3.2.4 。下载时记得将自带的Example.jar 也下载下来,这个里面提供了一些JNA的例子,通过这个能够更快的了解JNA。
使用JNA的调用本地方法的时候需要自定义数据结构,下面我们通过调用Windows提供的的锁定工作站方法来了解一下JNA。
1、首先查询Windows API知道锁定工作站的方法在user32.dll中定义,接下来定义一个接口来继承JNA的Library.java接口,用作声明DLL库文件,这里我们就把它命名为User32:
public interface User32 extends Library {}
2、查询user32.dll提供的API得知锁定工作方法是LockWorkStation,返回类型是boolean型,在User32.java中新增相应的方法:
boolean LockWorkStation();
这样我们的User32.java这个类就定义好了。接下来我们写测试程序进行调用。
3、编写测试类比如LockWorkStation.java,首先通过JNA的Native类加载对应的dll:
User32 user32 = (User32) Native.loadLibrary("user32", User32.class);
然后就可以调用LockWorkStation方法了,完整代码如下:
public class LockWorkStation {
public static void main(String[] args) {
User32 user32 = (User32) Native.loadLibrary("user32", User32.class);
user32.LockWorkStation();
}
}
这里说明一下loadLibrary方法中第一个参数是需要加载的dll文件名称,第二个参数的作用是让JNA使用这个类的加载器去加载DLL文件,加载顺序是,先从Users.class类的当前文件夹找,如果没有找到,再在工程当前文件夹下面找win32/win64文件夹,找到后搜索对应的dll文件,如果找不到再到WINDOWS下面去搜索,再找不到就会抛异常了。以TWAINDSM.dll将文件放到工程的根文件夹可以按照下面这个格式放:
上面的User32定义的是dll库文件,有时会碰到比如HANDLE、POINT、WORD和MSG等数据类型,有些数据类型JNA中没有提供,需要自己定义,根据作用的不同,定义的时候继承的父类也不一样,比如HANDLE定义方法是:
class HANDLE extends PointerType {
private boolean immutable;
public HANDLE() { }
public HANDLE(Pointer p) { setPointer(p); immutable = true; }
public Object fromNative(Object nativeValue, FromNativeContext context) {
Object o = super.fromNative(nativeValue, context);
if (INVALID_HANDLE_VALUE.equals(o))
return INVALID_HANDLE_VALUE;
return o;
}
public void setPointer(Pointer p) {
if (immutable)
throw new UnsupportedOperationException("immutable reference");
super.setPointer(p);
}
}
HANDLE被定义为类型安全的指针。而POINT用作表示坐标,不需要这么复杂,定义方式为:
class POINT extends Structure {
public int x, y;
public POINT() { }
public POINT(int x, int y) { this.x = x; this.y = y; }
}
使用JNA的过程中也不一定会一帆风顺,比如会抛出”非法内存访问”,这时候检查一下变量是否==null。还有内存对齐的问题,当从内存中获取图片信息进行保存的时候,如果内存对齐处理不好,就会抛出很严重的异常,导致JVM异常退出,JNA提供了四种内存对齐的方式,分别是:ALIGN_DEFAULT、ALIGN_NONE、ALIGN_GNUC和ALIGN_MSVC。ALIGN_DEFAULT采用平台默认的对齐方式(推荐);ALIGN_NONE是不采用对齐方式;ALIGN_GNUC为针对linux/gcc操作系统的对齐方式。ALIGN_MSVC为针对win32/msvc架构的内存对齐方式。
JNA也提供了一种保护机制.比如防止JNA出现异常不会导致JVM异常退出,默认是开启这个功能的,开启方式为 System.setProperty(“jna.protected”,”true”); 记得要在JNA加载dll文件之前调用,然后try {...} catch(Throwable e)异常,不过你也不要期望过高,不要以为加上这个就万事大吉,出现”非法内存访问”的时候还是会束手无策。JNA也提供了一种保护机制.比如防止JNA 出现异常不会导致JVM异常退出,默认是开启这个功能的,开启方式为 System.setProperty(“jna.protected”,”true”); 记得要在JNA加载dll文件之前调用,然后try {...} catch(Throwable e)异常,不过你也不要期望过高,不要以为加上这个就万事大吉,出现”非法内存访问”的时候还是会束手无策。
分享到:
相关推荐
### Java JNA 使用参考手册知识点概述 #### 一、JNA简介 JNA(Java Native Access)是一个基于经典JNI技术的Java开源框架,它允许Java应用程序动态地访问本机库,例如Windows系统的.dll文件,而无需编写任何JNI或...
自己写的dll文件,用以java jna调用测试用途自己写的dll文件,用以java jna调用测试用途自己写的dll文件,用以java jna调用测试用途自己写的dll文件,用以java jna调用测试用途
Java JNA调用PyTorch C++模型推理是一种在Java应用程序中利用PyTorch的深度学习能力的方法。JNA(Java Native Access)是Java平台上的一个库,它允许Java代码直接调用本机库(如C++编写的库),而无需编写JNI(Java ...
为了实现这种通信,我们可以使用Java Native Access(JNA),它是一种无需编写原生代码就能直接调用操作系统API或其他本地库的Java库。本篇文章将详细介绍如何将C++的头文件转换为Java的JNA接口类,以便于Java程序...
Java JNA(Java Native Access)是一种库,允许Java程序直接调用本地平台的API,无需编写C代码或使用JNI(Java Native Interface)。在本例中,“java jna 调用dll例子”指的是使用JNA在Java应用程序中调用Windows上...
Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接调用操作系统提供的本地库函数,而无需编写C/C++的中间层,如JNI(Java Native Interface)。"jna-demo.zip_DEMO_JNA demo_java jna_jna的...
本教程将详述如何使用C++编写DLL动态链接库,并通过Java的Java Native Access (JNA)库进行调用,从而实现Java程序对C++功能的调用。 首先,我们需要了解DLL是什么。DLL(Dynamic Link Library)是Windows操作系统中...
Java通过JNA(Java Native Access)与C语言交互是一种常见的技术,特别是在需要访问操作系统底层功能或利用已有的C库时。本示例是关于如何在Java中使用JNA处理C语言返回的结构体数据。下面将详细介绍这个过程,以及...
Java JNA(Java Native Access)平台是一个强大的库,允许Java应用程序直接调用操作系统原生API,无需编写C语言的JNI(Java Native Interface)代码。它为Java开发者提供了一种简单、安全的方式,来与底层操作系统...
java使用jna开启关闭第三方应用程序,附简单的例子,打开一个记事本,朋友们也可以改为自己需要打开的应用程序
在这种场景下,Java Native Access (JNA) 库为我们提供了一个无需编写C语言桥接代码就能调用系统原生库(如动态链接库DLL在Windows上)的解决方案。 本文将详细介绍如何使用Java通过JNA调用系统API,以Windows系统...
Java Native Access(JNA)是Java平台上的一个开源库,它提供了直接调用系统DLL函数的能力,无需编写C代码或者使用JNI(Java Native Interface)。本实例将深入探讨如何使用JNA调用DLL,并涵盖了各种参数类型,包括...
为了弥补这个不足,开发人员可以使用Java Native Access (JNA),这是一个Java平台上的库,允许Java代码调用本机库函数,与操作系统进行更直接的交互。 JNA是Java与本机代码之间的一个桥梁,它消除了编写C/C++头文件...
Java Native Access(JNA)是Java平台上的一个库,它允许Java代码直接调用本地(操作系统级别的)函数,而无需编写任何JNI(Java Native Interface)代码。JNA通过提供一个映射机制,将Java方法与C/C++函数相对应,...
Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接与本地操作系统API交互,无需编写C语言的JNI(Java Native Interface)代码。JNA通过提供一种高级映射机制,使得开发者可以方便地调用本地...
Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码与本地操作系统功能进行交互,无需编写C语言的动态链接库(DLL)或JNI(Java Native Interface)代码。JNA通过一种声明式的接口,使Java程序员...
标签:java、jna、中文文档、jar包; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。
Java Native Access (JNA) 是一个Java库,允许Java程序与本地平台API进行交互,而无需编写JNI(Java Native Interface)代码。JNA Platform是JNA的一个扩展,提供了对特定操作系统功能的访问,特别是针对Windows、...
Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接与本地操作系统API交互,无需编写C/C++的桥接代码。JNA提供了动态加载.dll(Windows)或.so(Linux/Unix)文件的能力,使得Java应用程序能够...