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;
        }
    }

}

 

posted @ 2022-07-18 15:46  一文搞懂  阅读(2351)  评论(2编辑  收藏  举报