第一部分:简单了解DLL里的函数
1、创建一个动态链接库项目testJNA
2、在头文件里声明函数
IRIS_SDK_API int STDCALL ik_release_enroll_device (IK_ENROLL_DEVICE_HANDLE dev_handle);
3、在源码里实现函数
int STDCALL ik_release_enroll_device (IK_ENROLL_DEVICE_HANDLE dev_handle) {
printf(“。。。。”);
return 1;
}
4、生成dll文件:testJNA.dll
5、将要调用的函数所在dll以及这些dll所依赖的dll都拷贝到windows/system32下(一定要将所有依赖的dll都找到,可以到网上下载个工具)
第二部分:JNA调用DLL的函数
JNA使用一个java接口来代表一个动态链接库发布的所有函数。
对于不需要的原生函数,可以不在java接口中声明java方法原型。
5、定义一个表示链接库的接口,如果dll是以stdcall方式输出函数,那么就继承StdCallLibrary。否则就继承默认的Library接口。此接口里定义一个实例
TestJnaLib INSTANCE = (TestJnaLib)Native.loadLibrary((Platform.isWindows() ? "testJNA.dll" : "c"), TestJnaLib.class);//标蓝的地方一定要这么写
此实例由jna通过反射自动生成。
此接口支持在Java端多线程、并发调用本地方法。如果本地类库不是线程安全的,可用
TestJnaLib INSTANCE2 = Native.synchronizedLibrary(INSTANCE);
来阻止多线程同时访问本地代码。
6、在表示链接库的接口里定义对应dll里的方法
int ik_release_enroll_device(Object devHandle);
7、调用本地方法
TestJnaLib.INSTANCE.ik_release_enroll_device(devHandle);
第三部分:DLL函数对JNA的回调
1、dll中定义了如下带回调函数的函数
IRIS_SDK_API int STDCALL ik_init_enroll_module (ik_ipaddress_t listened_addr,
int (__stdcall * IK_IDEN_CALLBACK_FUNC)
(IK_IDEN_DEVICE_HANDLE dev_handle, // 设备句柄
int type, // 回调类型
void *param); )
红色加粗部分是函数指针。
2、Java部分定义一个回调接口
必须继承自com.sun.jna.Callback接口 (如果回调函数是以stdcall输出,有时候可能引起jvm崩溃,可以改成继承StdCallCallback接口试试,)
子接口必须定义单个公有方法或一个名为callback的公有方法。必须持有到回调对象的一个存活引用。一个回调应该不抛出异常。
public interface FunCallBack extends StdCallCallback{
public int callback(IntByReference devHandle,int type,Pointer para);
}
callback方法里的参数顺序,类型及返回类型必须与C函数的相关类型对应上
3、定义回调接口的实现
public class CallbackFunImpl implements FunCallBack {
@Override
public synchronized int callback(IntByReference devHandle, int type, Pointer para){
//已知para是指向IkIdenresultArray类型的指针
IkIdenresultArray ikArray = new IkIdenresultArray(para);
int count = ikArray.result_count;
if(ikArray.presult == null || count <= 0){
log.info("识别结果数不大于0!");
return 0;
}
IkIdenresult[] rels = (IkIdenresult[])ikArray.presult.toArray(count);
if (rels == null || rels.length == 0) {
log.info("识别结果为空!");
return 0;
}
}
}
上文涉及的结构体的定义如下:
//识别结果列表
public static class IkIdenresultArray extends Structure{
public IkIdenresultArray(Pointer p) {
super(p);
useMemory(p);
read();
}
public IkIdenresultArray() {
super();
}
public static class ByReference extends IkIdenresultArray implements Structure.ByReference { }
public static class ByValue extends IkIdenresultArray implements Structure.ByValue{ }
public IkIdenresult.ByReference presult = new IkIdenresult.ByReference(); // 识别结果列表(表示指针)
public int result_count ; // 识别结果个数
}
4、在表示链接库实现的接口里定义要回调的本地函数
void methodWithCallback(StdCallCallback callback, int left, int right);
本地函数的函数指针用Callback 接口替代。
5、调用带函数指针的本地函数
TestJnaLib.INSTANCE.methodWithCallback(new CallbackFunImpl(), 4, 6)
最好将标红的地方定义一个static的变量引用它,否则回调函数的内存区域可能被GC回收而引起JVM崩溃,调用如下:
StdCallCallback callback = new CallbackFunImpl();
TestJnaLib.INSTANCE.methodWithCallback(callback, 4, 6)
第四部分:JAVA与C类型的对应
1、 基本类型的对应可以到网上查找对应表
2、 特殊的struct类型
1>Structure属性传递给本地字段必须是public的。
2>虽然结构体和结构体字段的名字可以是任意的,但他们应该尽可能接近本地定义。参数名及参数顺序对应一样。
3> Structure类的write()方法会把结构体的所有字段固定住,是原生函数可以访问。
4> C语言是不知道你Java的引用的。它只能访问固定的内存地址。因此,在使用JNI和JNA时,都会把Java对象锁住。GC不再管理。不删除,也不移动位置。即把传递给C的struct对象A固定住内存,如果这个A种还嵌套了struct对象,则也被固定住,但是如果嵌套的是struct的引用B,则不会固定,需要把B手动固定,如:
B.ByReference b = new B.ByReference();
b.write();
5> 结构体的定义如:
//识别结果
public static class IkIdenresult extends Structure{
//属性都定义为public类型
public IkIdenresult() {
super();
}
public IkIdenresult(Pointer p) {
super(p);
useMemory(p);
read();
}
public static class ByReference extends IkIdenresult implements Structure.ByReference { }//通过ByReference定义的是指针
public static class ByValue extends IkIdenresult implements Structure.ByValue{ }//通过ByValue定义的是对象
public IntByReference dev_handle; // 识别设备句柄
public byte []dev_sn = new byte[128];// 设备标志
public byte []iden_date_time = new byte[32]; // 识别时间
public int person_id; // personID
public byte [] person_name= new byte[128]; // 人员姓名
public int feature_id; // featureID
public int eye_flag; // 眼睛标志
}
相关推荐
在“JNA调用DLL完整实例demo”中,我们首先需要创建一个Java接口,这个接口将代表DLL中的函数。例如,如果DLL中有一个名为`recvWork`的函数,我们的Java接口可能会这样定义: ```java public interface ...
总结来说,JNA调用DLL的关键步骤包括:定义DLL接口,加载DLL,调用DLL函数,并处理可能出现的编码问题。本实例提供了一个具体的应用场景,有助于理解JNA调用DLL的过程,并解决了常见的中文乱码问题。通过学习和实践...
在使用JNA调用DLL的过程中,可能会遇到内存溢出的问题。这类问题通常发生在处理大量数据或长时间运行的应用场景中。为了避免这种情况,可以采取以下措施: - **优化数据结构**:合理设计数据结构,减少不必要的数据...
总结,Android通过JNA调用C/C++方法是一个高效且方便的方式,它减少了JNI的繁琐步骤,使Java开发者能更容易地利用C/C++代码。不过,在追求性能或处理复杂数据结构时,可能需要考虑使用JNI。正确理解和使用JNA,可以...
本实例将深入探讨如何使用JNA调用DLL,并涵盖了各种参数类型,包括基本数据类型、指针、结构体、回调函数、字符串以及数组。 首先,理解JNA的基本工作原理至关重要。JNA通过映射DLL中的函数到Java类的方法来实现...
java调用C#封装的dll(jna,com)java调用C#封装的dll(jna,com)java调用C#封装的dll(jna,com)
采用java jna4.1 调用C编写的dll文件,获得返回结果,且获得返回参数的例子
通常,这可能是一个测试类或者包含主方法的Java文件,用于演示如何使用JNA调用DLL的具体代码。由于没有详细文件内容,我们将基于JNA的一般用法进行讨论。 在Java中使用JNA调用DLL的基本步骤如下: 1. **添加JNA库*...
在标题中提到的“JNA调用.dll文件或.so动态链接库的代码demo”,这是一个实际应用JNA来调用本地动态库的示例。下面我们将深入探讨JNA的工作原理、使用步骤以及如何处理.dll和.so文件。 1. **JNA工作原理**: JNA...
在"jna调用C jna jni dll"的标签中,我们可以看到这四个关键词。JNA是主要的技术,而"C"代表我们要调用的本地库是用C语言编写的。JNI虽然不是本次讨论的重点,但它是另一种常见的与本地代码交互的方式。"dll"再次...
自己写的dll文件,用以java jna调用测试用途自己写的dll文件,用以java jna调用测试用途自己写的dll文件,用以java jna调用测试用途自己写的dll文件,用以java jna调用测试用途
Java Native Access(JNA)是Java平台上的一个开源库,它允许Java代码直接调用操作系统提供的原生API...通过学习和实践这个"jna调用C++ dll"的例子,你将能够熟练地处理跨语言的交互,包括处理回调函数这样的高级特性。
java后端springBoot框架使用jna调取C语言的dll接口(停车场道闸接口) 包含构造体的调用, 回调函数的调用,JNA和C / C ++的数据类型映射,Pointer类型的使用
2. **Java JNA调用C++ DLL**: - 引入JNA库到Java项目。JNA提供了一种无需编写JNI(Java Native Interface)代码即可调用本地方法的方式。 - 定义C++接口的Java映射类,使用JNA的`Interface`和`Native`类: ```...
研究java调用dll的时候,大部分都是通过jni,比较麻烦,我找到了通过jna方法调用dll的方法,用起来比较方便,只需要引用jna.jar包,这个jar包已经包含在程序中,还包含了我调用dll的遇到难道的解决办法。
**JNA 调用DLL步骤** 1. **创建接口**: 创建一个Java接口,声明本地库中的函数签名。每个方法都应使用`native`关键字,并指定适当的返回类型和参数类型。 2. **加载库**: 使用 `Library` 接口的子类,如 `...
本实例将详细介绍如何使用JNA调用DLL动态链接库,通过一个超简单的Demo来展示其过程。 首先,我们需要了解JNA的基本工作原理。JNA通过映射Java方法到本地库中的函数,实现了跨语言的通信。在Java中,我们定义一个...
标题中的“最简单的JNA调用DLL”是指Java Native Access(JNA)库在Java程序中调用Windows Dynamic Link Library (DLL) 文件的一种基础方法。JNA是Java平台上的一个开源库,它允许Java代码与本地平台API进行交互,...
Java通过JNA调用DLL,可以利用C/C++等编写的本地库功能。 3. **回调函数**:在C/C++编程中,回调函数是指被其他函数调用的函数。在Java通过JNA调用DLL时,如果DLL函数需要一个回调函数作为参数,那么Java需要定义一...
在本例中,“java jna 调用dll例子”指的是使用JNA在Java应用程序中调用Windows上的动态链接库(DLL)文件,这里特别提到了大华SDK的Dll,这通常用于处理视频流和视频播放功能。 大华SDK( Dahua Software ...