JNA传入char[][]和具有联合体结构对象数组

2023-10-27

工作中根据施工现场需要,我们需要通过API接口获取对方系统内数据,但是API接口方法参数如下:

DWORD getSnapshot(DBPH  h, char Names[][80],TVVAL tvs[],int size)

其中包含了char的双重数组,一个包含联合体的对象数组(该数组传入后,返回数据)。

联合体数据对象如下:

typedef struct  t_vval		//变体结构
{
	DWORD	vt;		
	long	len;	
					
	union 	
	{
		long  	lval;		
		float  	fval;		
		__int64 llval;		
		double 	dblval;	
	};
	long  time;				
	short snerr;			
}TVVAL,*LPVVAL; 

原理我也不多讲(深究我也不会,能用就行2333),我直接说一下char双重数组和联合体对象我是如何解决的:

java实现C接口方法如下:

int DBP_GetSnapshot(Pointer h, byte[] Names, TVVAL tvs[], int nsize);

char[][]:

char[][]传输和char**是不同的,我开始时使用的string[]去尝试,发现对方厂家打印的Names名称居然是表示地址的乱码字符串。

问了下公司C语言部门的同事,他建议:直接用java把每个字符串转化为固定长度的byte[],将byte数组传入,C语言接收char[][]数据的时候要的是值并不是内存地址。经过实践发现该方法是可行的,对方的程序能够正确打印Names字段里的数据内容。

联合体结构:

联合体结构我按照网上搜索的,写出了如下结构:

public class TVVAL extends Structure {// 变体结构

	
	public int vt;
	public int  len; 
	public field1_union field1;
	public int time; 
	public short snerr; 
	
	

	public static class field1_union extends Union {
		public long  lval;
		public float fval;
		public long  llval ;
		public double dblval;
	}
	public static class ByReference extends TVVAL implements Structure.ByReference {
	}

	public static class ByValue extends TVVAL implements Structure.ByValue {
	}

	
	@Override
	protected List<String> getFieldOrder() {
		return Arrays.asList(new String[] { "vt", "len", "field1", "time", "snerr" });

	}

}

但是该结构可以传入,并且拿到前俩个值,但是到联合体结构后数据都没写入,我各种方法尝试老半天也不成功,与此同时协助我的同事突然发现了一个神奇的工具包JNAerator(参考网址:jnaerator:java调用动态库的神器,JNA代码自动生成工具_10km的专栏-CSDN博客,这玩意可以根据dll和so等文件直接生成jna对应的java类,尝试了下其生成的对象就可以让数据写入对象,java可以顺利取到数据,修改后的对象代码如下(相比于我的代码,多了一些声明方法,可能该方法可让jna将对象处理成C语言可写入的形式):

public class TVVAL extends Structure {// 变体结构
	public int vt;
	public int  len; 
	public field1_union field1;
	public int time; 
	public short snerr; 
	
	public static class field1_union extends Union {
		public long  lval;
		public float fval;
		public long  llval ;
		public double dblval;

		public field1_union() {
			super();
		}
		public field1_union(int lval) {
			super();
			this.lval = lval;
			setType(Integer.TYPE);
		}	
		public field1_union(float fval) {
			super();
			this.fval = fval;
			setType(Float.TYPE);
		}
		public field1_union(long llval) {
			super();
			this.llval = llval;
			setType(Long.TYPE);
		}
		public field1_union(double dblval) {
			super();
			this.dblval = dblval;
			setType(Double.TYPE);
		}
		public static class ByReference extends field1_union implements Structure.ByReference {
			
		};
		public static class ByValue extends field1_union implements Structure.ByValue {
			
		};
	}
	
	public static class ByReference extends TVVAL implements Structure.ByReference {
	}

	public static class ByValue extends TVVAL implements Structure.ByValue {
	}

	public TVVAL() {
		super();
	}
	public TVVAL(int vt, int len, field1_union field1, int time, short snerr) {
		super();
		this.vt = vt;
		this.field1 = field1;
		this.time = time;
		this.snerr = snerr;
	}
	public TVVAL(Pointer peer) {
		super(peer);
	}
	
	@Override
	protected List<String> getFieldOrder() {
		return Arrays.asList(new String[] { "vt", "lvlen", "field1", "ltime", "snerr" });

	}

}

在对象联合体内取值的方法如下:

private void getvalue(TVVAL tvval) {
		int i = (Integer) tvval.readField("vt");
		short err = (short) tvval.readField("snerr");
		field1_union v = (field1_union) tvval.readField("field1");
        System.out.println(v.lval);
		System.out.println(v.fval);
		System.out.println(v.llval);
		System.out.println(v.dblval);
}

贴吧啥的求助好几天没人回答,在此发文,希望对同行们有所帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JNA传入char[][]和具有联合体结构对象数组 的相关文章

随机推荐

  • Less-7(文件读写操作)

    文章目录 OUTFILE注入 实战 1 关卡分析 2 过关斩将 2 1 secure file priv 2 2 注入过程 load file的使用 SQLmap OUTFILE注入 在前面的学习中 我们知道了sql注入中的盲注和双注入是个
  • CentOS 代理 proxy设置方法

    说明 为什么说是http代理 其实这个还不能说是全称走代理 罪名写的区别就是ICMP协议这个设置就无效 只能说是90 的应用都可以使用这个设置来实现代理访问 只有个别不行 比如一些软件根本不走http协议的 那么此种方法绝对不行 下面是讲解
  • 利用VC++编程实现程序自动启动

    摘要 在工作中经常遇到一些程序 当计算机启动时会自动将该程序加载 以实现对计算机的监控等特殊的目的 本文就针对这个问题 阐述了系统加载特定程序的原理和方法 同时利用VC 6 0编程实现这种特定的功能的 并对其中的关键代码进行了分析 工作中经
  • Peewee进阶

    Part1前言 接上篇文章 如果我们想要修改表结构或者字段属性该如何操作呢 带着这个问题 今天我们就一起来了解 peewee 的进阶操作 Part2关于 playhouse peewee 有很多的扩展 这些扩展都集中收录在 playhous
  • 网线分类解析

    网线的类别分几个维度去看 1 屏蔽双绞线 STP 屏蔽双绞线 是一种特殊的网线 它比非屏蔽双绞线多一道工序 网线内部信号线的外面包裹着一层金属网 在屏蔽层外面才是绝缘外皮 屏蔽层可以有效地隔离外界电磁信号的干扰 这种网线多用于布设网线的环境
  • 三维重建工具——pclpy使用教程

    最近试了试用pclpy这个库进行点云处理 在此对pclpy的使用进行一个总结 更全的pclpy教程 代码完全开源 github 欢迎fork star 相关文章 pclpy安装 文章目录 pclpy相关 开发环境 文件结构 I O读取 构造
  • Git基础操作:push提交多个文件成功后如何撤销回退某个文件,回退代码到某次commit

    之前写过类似的一篇文章 Git基础操作 push提交成功后如何撤销回退 回退代码到某次commit 按照那个示例 把期间所有commitid下的文件都会回滚掉 但是如果只想将其中某个文件回滚可以下面的示例来搞 git log OneBean
  • Broyden算法

    代码传送门 https github com taifyang optimization method Python实现 import sympy import numpy as np from numpy import matlib as
  • java毕业设计——基于Java+AI的五子棋游戏设计与实现(毕业论文+程序源码)——五子棋游戏

    基于Java AI的五子棋游戏设计与实现 毕业论文 程序源码 大家好 今天给大家介绍基于Java AI的五子棋游戏设计与实现 文章末尾附有本毕业设计的论文和源码下载地址哦 需要下载开题报告PPT模板及论文答辩PPT模板等的小伙伴 可以进入我
  • expiringmap入门初体验

    功能简介 可设置Map中的Entry在一段时间后自动过期 key过期 value同时会过期 可设置Map最大容纳值 当到达Maximum size后 再次插入值会导致Map中的第一个值过期 可添加监听事件 在监听到Entry过期时调度监听函
  • linux系统中docker服务和普通服务对外访问端口不通的问题

    linux系统中docker服务和普通服务对外访问端口不通的问题 前一段时间 在一个新的centos 7 4 服务器上运行项目 共有四个项目 因为特殊原因 两个是通过docker 运行 另外两个是通过nginx和tomcat 运行 当运行起
  • 电脑配置tomcat环境变量

    Tomcat在使用前需要配制环境变量 这里以Tomcat9为例进行配置 下载Tomcat压缩包 Tomcat8 链接 https pan baidu com s 109DSHjX3 Gk7lVRVre3xxw 提取码 lsro Tomcat
  • 使用maven依赖的方式引入jQuery

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 加入依赖
  • 栈、队列的链式存储结构

    栈 再说链表的实现栈之前 我们先回顾一下什么是栈 栈基本概念 栈 stack 是限定在表尾进行插入和删除操作的线性表 或单链表 只能在一段进行插入和删除 因此不存在 在中间进行插入 栈顶 top 允许插入和删除的一端 而另一端称为栈底 bo
  • 指定CUDA版本失败的解决方案

    新电脑安装的WIN11系统 因为CUDA只有11和12目前能装到WIN11上 所以就装了一个CUDA 11 7 但是编译PBRT失败 所以无奈之下又装了CUDA 12 但是因为我有的代码需要CUDA 11里的函数 这些函数在CUDA12里被
  • python编程:numpy包

    numpy是使用Python进行科学计算的基本软件包 它包含以下内容 强大的N维数组对象 复杂的 广播 功能 集成C C 和Fortran代码的工具 有用的线性代数 傅立叶变换和随机数功能 我们先比较一下numpy和list的运算速度 比如
  • matlab图像处理系列:图片圈数识别+编号标记位置

    matlab图像处理系列 图片圈数识别 编号标记位置 一 app界面介绍 二 实现过程 step1图像二值化 step2 图像close 做差 step3 像素阈值处理 step4 清除小区域 step5 识别联通区域 并在原图上标记 三
  • 3D空间包围球(Bounding Sphere)的求法

    引言 在3D碰撞检测中 为了加快碰撞检测的效率 减少不必要的碰撞检测 会使用基本几何体作为物体的包围体 Bounding Volume BV 进行测试 基本包围体的碰撞检测相对来说便宜也容易的多 所以如果在基本包围体的碰撞检测中都没有通过的
  • Docker Registry深度历险

    目录 前言 环境 问题缘起 安装本地Registry minikube访问共享image 前言 上篇我们对Docker整体有了一定了解 知道了其中一个核心概念是Registry 下来就进行更深入的学习 环境 环境 mac mini M1芯片
  • JNA传入char[][]和具有联合体结构对象数组

    工作中根据施工现场需要 我们需要通过API接口获取对方系统内数据 但是API接口方法参数如下 DWORD getSnapshot DBPH h char Names 80 TVVAL tvs int size 其中包含了char的双重数组