Java调用C/C++动态链接库函数,当传递参数为结构体且结构体存在数组的情况时,则传参的数组长度要和C/C++语言定义的长度一致。
import java.util.ArrayList; import java.util.List; import com.sun.jna.Structure; /** * * @author XIVA * */ public class DevInfo extends Structure { public byte[] pProtocolType = new byte[20]; public int nDevType = 0; public byte[] pDevIP = new byte[20]; public int nDevPort = 0; public byte[] pDevUsername = new byte[64]; public byte[] pDevPassword = new byte[64]; public byte[] pVendorType = new byte[20]; public static class ByReference extends HwDevInfo implements Structure.ByReference { } public static class ByValue extends HwDevInfo implements Structure.ByValue { } @Override protected List<String> getFieldOrder() { List<String> fieldOrderList = new ArrayList<String>(); fieldOrderList.add("pProtocolType"); fieldOrderList.add("nDevType"); fieldOrderList.add("pDevIP"); fieldOrderList.add("nDevPort"); fieldOrderList.add("pDevUsername"); fieldOrderList.add("pDevPassword"); fieldOrderList.add("pVendorType"); return fieldOrderList; } }
接口声明:
public int Camera_AddDevice(String pTargetDomainCode, String pTargetDevGroupID, DevInfo.ByReference pDevInfo, byte[] pDevCode);
结构体声明:
typedef struct _DevInfo { char pProtocolType[20]; int nDevType; char pDevIP[20]; int nDevPort; char pDevUsername[64]; char pDevPassword[64]; char pVendorType[20]; _DevInfo() { nDevPort = 0; nDevType = 0; ZeroMemory(pProtocolType, sizeof(pProtocolType)); ZeroMemory(pDevIP, sizeof(pDevIP)); ZeroMemory(pDevUsername, sizeof(pDevUsername)); ZeroMemory(pDevPassword, sizeof(pDevPassword)); ZeroMemory(pVendorType, sizeof(pVendorType)); } }DEVINFO, *LPDEVINFO;
#define JNAAPI extern "C" _declspec(dllexport) JNAAPI int Camera_AddDevice(const char * pTargetDomainCode, const char * pTargetDevGroupID, LPDEVINFO pDevInfo, OUT char * pDevCode);
声明了以上函数后,就是JAVA调用了。
DevInfo.ByReference pDevInfo = new DevInfo.ByReference(); byte[] ipBytes = "127.0.0.1".getBytes(); byte[] pDevUsernameBytes = "admin".getBytes(); byte[] pDevPasswordBytes = "admin".getBytes(); byte[] pVendorTypeBytes = "xxx".getBytes(); byte[] pProtocolTypeBytes = "xxx".getBytes(); System.arraycopy(ipBytes, 0, pDevInfo.pDevIP, 0, Math.min(ipBytes.length, pDevInfo.pDevIP.length)); System.arraycopy(pDevUsernameBytes, 0, pDevInfo.pDevUsername, 0, Math.min(ipBytes.length, pDevInfo.pDevUsername.length)); System.arraycopy(pDevPasswordBytes, 0, pDevInfo.pDevPassword, 0, Math.min(ipBytes.length, pDevInfo.pDevPassword.length)); System.arraycopy(pVendorTypeBytes, 0, pDevInfo.pVendorType, 0, Math.min(ipBytes.length, pDevInfo.pVendorType.length)); System.arraycopy(pProtocolTypeBytes, 0, pDevInfo.pProtocolType, 0, Math.min(ipBytes.length, pDevInfo.pProtocolType.length)); pDevInfo.nDevPort = 8080; pDevInfo.nDevType = 1; String pDevCode = CommHWService.Camera_AddDevice("xxxx", "0", pDevInfo);
其中最为重要的代码是将值复制到声明的内存区域,
System.arraycopy(ipBytes, 0, pDevInfo.pDevIP, 0, Math.min(ipBytes.length, pDevInfo.pDevIP.length));
,而不是直接赋值:pDevInfo.pDevUsername = "admin".getBytes();
如果使用以下方式实现,内存会发生泄漏,导致JVM报错。
原因就是JVM声明的结构体和C端定义的结构体对应的内存区域大小不一致。
另外:
1、对象pDevInfo初始化的时候没有初始化其属性,则可以使用工具类Arrays的方法public static byte[] copyOf(byte[] original, int newLength)。
2、当传递参数为结构体数组时,我们需要使用连续的内存区域。可以使用反射类Array来初始化对象。如:((DevInfo[])Array.newInstance(DevInfo.class, 10));
参考:http://tcspecial.iteye.com/blog/1665583
相关推荐
JNA 复杂结构体传递 结构体数组,结构体指针 查询很多资料才整合!
Java调用C语言动态库(JNA方式):回调函数、结构体数组传参、结构体数组返回-附件资源
详细演示了如何通过JNA实现以下形式的动态链接库接口: 1:基本数据类型 2:基本数据类型的指针和引用 3:结构体 4:结构体的指针和引用 5:函数指针和回调函数 6:字符串指针 7:输入一个数组 8:输出一个数组并...
经过几天的奋战,终于让我搞懂了JNA的解析以及指针在结构体中的应用!!!下了很多的资料,里面包含c++的.h头文件,给需要帮助的人看看!! 里面包含代码以及解析过程。
java通过jna调用c返回结构体例子,就是解决c语言返回结构体,java用类对象接收,包含jar包,java文件,c文件,操作步骤文档,在linux下完美通过
jna,java,jni解放螺丝钉解放福建省电力附近 范德萨会计法
java获取dll动态库源码分享。通过jna加载动态库,然后初始化动态库,打开动态库,在通过指针获取动态库里面的数据。
JNA调用C++动态库,传入二维数组,通过C++返回二维数组,java调用C++完整案例
深入解析JNA—模拟C语言结构体
jna调用动态库的一般步骤,以及操作的实例,具体步骤的解析
将多个变量放到一个结构体中,减少函数传递时的多个参数传进传出的复杂性 结构体传进函数时,是以引用的形式传入的,不是以指针的形式。
这个是使用JNA调用.dll文件或.so文件动态链接库的例子
假如有一个现有的 .dll/.so 文件,假如使用 JNI 技术调用,我们首先需要另外使用 C 语言写一个 .dll/.so 共享库,使用 SUN 规定的数据结构替换 C 语言的数据结构,调用已有的 ? dll/so 中公布的函数。 然后再在 Java...
java调用动态链接库例程(测试通过)及库包 jna4.3 完整资源,demo。 jna 4.3 、示例 dll ,调用demo
Jna调用dll动态库相关jar包,其中包括jna-3.5.1.jar和platform-3.5.1.jar
jni调用C++动态库,jna调用C++动态库,eclipse maven project
JNI入门级参考文档,尤其适用第一次编写JNI的初学者。
NULL 博文链接:https://songwensheng.iteye.com/blog/676714