Structure.getFieldOrder() 错误解决办法

 

案例:在用java开发海康、大华、宇视 SDK的时候会用到Jna去调用dll库,但是由于各个厂家的SDK用到的Jna版本不同导致出现Structure.getFieldOrder()的错误。

 

原因:jna里面的Structure类在高版本需要重写getFieldOrder()才行。该方法是对类里面的变量名包装成List返回。如下:

public static class NET_DVR_ADDIT_POSITION extends Structure {//车载GPS信息结构(2007-12-27) public byte[] sDevName = new byte[32]; /* 设备名称 */ public int dwSpeed; /*速度*/ public int dwLongitude; /* 经度*/ public int dwLatitude; /* 纬度*/ public byte[] direction = new byte[2]; /* direction[0]:'E'or'W'(东经/西经), direction[1]:'N'or'S'(北纬/南纬) */ public byte[] res = new byte[2]; /* 保留位 */ //高版本方法覆盖 @Override protected List getFieldOrder() { return Arrays.asList("sDevName","dwSpeed","dwLongitude","dwLatitude","direction","res"); } }

 

 

 

解决办法

1、通常来说在所有继承Structure的类里面加上 getFieldOrder 方法就行了。

2、但是通常SDK里面的的类是成百上千的,因此我写了一个工具类来生成代码,通过正则表达式自动匹配类、变量名,往类里面添加getFieldOrder 方法(当然时间紧迫没考虑内部内部类的问题,将就着用一下,总比一个一个添加要好很多)

import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Stack; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 对继承Structure 的类 * 统一添加 getFieldOrder() 方法 * * 原理:在去除单行或者多行注释之后 代码的括号是成对存在的,把左括号压入栈,遇到右括号就出栈,最后一个括号出栈之前打印添加的方法 * */ public class AddGetFieldOrder3 { /** * 符号栈 */ static Stack<Character> stack = new Stack<>(); /** * 变量链表 */ private static LinkedList varNamelink = new LinkedList(); /** * 匹配 extends Structure 的类 */ static Pattern ptClassName = Pattern.compile("(?<=class ).*(?= extends Structure)"); /** * 匹配等号赋值的变量 去除等号前面的空字符(空格、制表符、换行符)、中括号 */ static Pattern ptValue1 = Pattern.compile("[A-Za-z0-9_]*(?=([\\]\\[\\s]*\\=))"); /** * 匹配分号赋值的变量 去除等号前面的空字符(空格、制表符、换行符)、中括号 */ static Pattern ptValue2 = Pattern.compile("[A-Za-z0-9_]*(?=([\\]\\[\\s]*;))"); /** * 匹配注释内容 */ static Pattern ptValue3 = Pattern.compile("/\\*[\\S\\s]*?\\*/|//.*"); public static void main(String[] args) throws IOException { String fileName = "dahua/lib/code.txt"; Path path = Paths.get(fileName); List<String> allLines = Files.readAllLines(path, StandardCharsets.UTF_8); List<String> newList = new ArrayList<>(); /** * 1、去除单行注释 */ for (String str : allLines) { String newStr = replaceAnnotate(str, ptValue3); newList.add(newStr); } /** * 2、去除多行注释 * 需要考虑 注释前后是否有代码 */ Boolean annotate = false; for (int i = 0; i < newList.size(); i++) { String s = newList.get(i); if (s.contains("*/")) { annotate = false; String afterStr = s.substring(s.indexOf("*/") + 2, s.length()); newList.set(i, afterStr); continue; } if (s.contains("/*")) { annotate = true; String foreStr = s.substring(0, s.indexOf("/*")); newList.set(i, foreStr); continue; } if (annotate) { newList.set(i, ""); continue; } } /** * 3、匹配需要处理的类 进行入栈出栈操作 */ Boolean openStack = false; for (int i = 0; i < newList.size(); i++) { String s = newList.get(i); if (matchs(s, ptClassName)) { //开始入栈 openStack = true; } if (openStack) { for (int j = 0; j < s.length(); j++) { char c = s.charAt(j); if (c == '(' || c == '{' || c == '[') { //入栈 stack.push(c); continue; } if (c == ')' || c == ']' || c == '}') { //出栈 stack.pop(); if(stack.empty()){ System.out.println(printFunc(varNamelink)); varNamelink.clear(); openStack=false; } continue; } } String val= match(s,ptValue1); if(val==null){ val= match(s,ptValue2); } if(!isBlank(val)){ varNamelink.add(val); } } System.out.println(allLines.get(i)); } } /** * 正则匹配 替换掉匹配到的元素 * * @param str * @param pt * @return */ static String replaceAnnotate(String str, Pattern pt) { StringBuilder sb = new StringBuilder(); Matcher matcher = pt.matcher(str); //开始匹配 while (matcher.find()) { // 替换所有匹配的数据 sb.append(matcher.replaceAll(" ")); } String res = sb.toString(); return res.isEmpty() ? str : res; } /** * 正则匹配 * * @param str * @param pt * @return 匹配到的元素 */ static String match(String str, Pattern pt) { Matcher matcher = pt.matcher(str); //开始匹配 while (matcher.find()) { String res=matcher.group(0); return "".equals(res)?null:res; } return null; } /** * 正则匹配 存在返回true * * @param str * @param pt * @return */ static Boolean matchs(String str, Pattern pt) { Matcher matcher = pt.matcher(str); //开始匹配 while (matcher.find()) { return true; } return false; } /** * 打印方法 * * @param linkedList * @return */ static String printFunc(LinkedList<String> linkedList) { StringBuilder sb = new StringBuilder(); sb.append(" //高版本方法覆盖\n"); sb.append(" @Override\n"); sb.append(" protected List getFieldOrder() {\n"); sb.append(" return Arrays.asList("); int size = linkedList.size(); int len=0; for (int i = 0; i < size; i++) { String var=linkedList.get(i); len+=var.length(); sb.append("\""); sb.append(var); sb.append("\""); if (i < size - 1) { sb.append(","); if(len>80){ len=0; sb.append("\n\t\t\t"); } } } sb.append(");\n"); sb.append(" }"); return sb.toString(); } /** * 是否为空 * @param cs * @return */ public static boolean isBlank(CharSequence cs) { int strLen = cs == null ? 0 : cs.length(); if (strLen == 0) { return true; } else { for(int i = 0; i < strLen; ++i) { if (!Character.isWhitespace(cs.charAt(i))) { return false; } } return true; } } }

 


__EOF__

本文作者如风
本文链接https://www.cnblogs.com/easyidea/p/16490708.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   一文搞懂  阅读(3515)  评论(2编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示