Java解析c与c++ 的.h文件中的结构体

Java解析c/c++ 的.h文件中的结构体

1.引入CDT工具包

        <dependency>
            <groupId>org.eclipse.core</groupId>
            <artifactId>org.eclipse.core.resources</artifactId>
            <version>3.7.100</version>
        </dependency>
        <dependency>
            <groupId>com.github.mhoffrog.attached</groupId>
            <artifactId>org.eclipse.cdt.core</artifactId>
            <version>5.11.0</version>
        </dependency>

2.实现代码

2.1初始化

    @SneakyThrows
    public List<CStructDeclaration> readStructCpp(String filePath) {
        CppFileParser parser;
        try {
            parser = new CppFileParser(filePath);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        return parser.getStructDeclaration();
    }

2.2解析头文件信息

//根据头文件路径,解析头文件信息

    private File headerFile;
    private IASTTranslationUnit unit;

public CppFileParser(String headerFilePath) throws Exception {
        headerFile = new File(headerFilePath);
        if (!headerFile.exists()) {
            throw new IllegalArgumentException("The header file don't exists");
        }
        unit = getTranslationUnit(headerFile);
        functions = new ArrayList<>();
    }



    IASTTranslationUnit getTranslationUnit(File source) throws Exception {
        FileContent reader = FileContent.create(source.getAbsolutePath(), getContentFile(source).toCharArray());

        return GPPLanguage.getDefault().getASTTranslationUnit(reader,
            new ScannerInfo(), IncludeFileContentProvider.getSavedFilesProvider(), null,
            ILanguage.OPTION_IS_SOURCE_UNIT, new DefaultLogService());
    }


 String getContentFile(File file) throws IOException {
        StringBuilder builder = new StringBuilder();
        String line;
        try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)))) {
            while ((line = br.readLine()) != null) {
                builder.append(line).append("\n");
            }
        }
        return builder.toString();
    }

2.3结构体解析

 /**
     * 解析头文件中的结构体
     */
    public List<CStructDeclaration> getStructDeclaration() {
        List<CStructDeclaration> cStructDeclarationList = new ArrayList<>();
        //结构体解析
        // 遍历抽象语法树(AST)以查找结构体及其成员
        IASTDeclaration[] declarations = unit.getDeclarations();
        for (IASTDeclaration declaration : declarations) {
            // 检查是否为简单声明
            if (declaration instanceof IASTSimpleDeclaration) {
                IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
                IASTDeclSpecifier declSpecifier = simpleDeclaration.getDeclSpecifier();
                // 检查声明规范是否为复合类型说明符(结构体)
                if (declSpecifier instanceof IASTCompositeTypeSpecifier) {
                    IASTCompositeTypeSpecifier compositeTypeSpecifier = (IASTCompositeTypeSpecifier) declSpecifier;
                    // 检查是否为结构体声明
                    if (compositeTypeSpecifier.getKey() == IASTCompositeTypeSpecifier.k_struct) {
                        // 获取结构体的名称
                        String structName = compositeTypeSpecifier.getName().toString();
                        System.out.println("找到结构体: " + structName);
                        //结构体数据填充
                        CStructDeclaration cStructDeclaration = new CStructDeclaration();
                        cStructDeclaration.setName(structName);

                        // 获取结构体成员
                        List<CStructMember> cStructMemberList = new ArrayList<>();
                        IASTDeclaration[] structMembers = compositeTypeSpecifier.getMembers();
                        for (IASTDeclaration member : structMembers) {
                            // 检查成员是否为简单声明
                            if (member instanceof IASTSimpleDeclaration) {
                                IASTSimpleDeclaration memberDeclaration = (IASTSimpleDeclaration) member;
                                IASTDeclarator[] declarators = memberDeclaration.getDeclarators();
                                for (IASTDeclarator declarator : declarators) {
                                    IASTPointerOperator[] pointerOperators = declarator.getPointerOperators();
                                    //指针属性判断获取
                                    if (pointerOperators.length > 0) {
                                        StringBuilder pointerType = new StringBuilder();
                                        for (IASTPointerOperator pointer : pointerOperators) {
                                            pointerType.append(pointer.getRawSignature());
                                        }
                                        IASTName memberNames = declarator.getName();
                                        String memberNameString = memberNames.toString();
                                        IASTDeclSpecifier memberTypeSpecifier = memberDeclaration.getDeclSpecifier();
                                        String memberTypeName = memberTypeSpecifier.getRawSignature();
                                        System.out.println(
                                            "  成员变量: " + memberTypeName + pointerType + " " + memberNameString);
                                        CStructMember cStructMember = new CStructMember();
                                        cStructMember.setType(memberTypeName + pointerType);
                                        cStructMember.setName(memberNameString);
                                        cStructMember.setArray(Boolean.FALSE);
                                        cStructMemberList.add(cStructMember);
                                    } else {
                                        // 获取成员变量名称
                                        IASTName memberName = declarator.getName();
                                        // 获取成员变量类型说明符
                                        IASTDeclSpecifier memberTypeSpecifier = memberDeclaration.getDeclSpecifier();
                                        String memberTypeName = memberTypeSpecifier.getRawSignature();
                                        String memberNameString = memberName.toString();
                                        //数组类型判断及初始化大小获取
                                        if (declarator instanceof IASTArrayDeclarator) {
                                            IASTArrayModifier[] arrayModifiers =
                                                ((IASTArrayDeclarator) declarator).getArrayModifiers();
                                            if (arrayModifiers.length > 0) {
                                                IASTExpression iastExpression =
                                                    arrayModifiers[0].getConstantExpression();
                                                if (Objects.isNull(iastExpression)) {
                                                    System.out.println(
                                                        "  成员变量: " + memberTypeName + " " + memberNameString + "[]");
                                                    CStructMember cStructMember = new CStructMember();
                                                    cStructMember.setType(memberTypeName);
                                                    cStructMember.setName(memberNameString + "[]");
                                                    cStructMember.setArray(Boolean.TRUE);
                                                    cStructMember.setArraySize(0);
                                                    cStructMemberList.add(cStructMember);
                                                } else {
                                                    int arraySize = Integer.parseInt(iastExpression.getRawSignature());
                                                    System.out.println(
                                                        "  成员变量: " + memberTypeName + " " + memberNameString + "[" + arraySize + "]");
                                                    CStructMember cStructMember = new CStructMember();
                                                    cStructMember.setType(memberTypeName);
                                                    cStructMember.setName(memberNameString + "[" + arraySize + "]");
                                                    cStructMember.setArray(Boolean.TRUE);
                                                    cStructMember.setArraySize(arraySize);
                                                    cStructMemberList.add(cStructMember);
                                                }
                                            }
                                        } else {
                                            System.out.println(
                                                "  成员变量: " + memberTypeName + " " + memberNameString);
                                            CStructMember cStructMember = new CStructMember();
                                            cStructMember.setType(memberTypeName);
                                            cStructMember.setName(memberNameString);
                                            cStructMember.setArray(Boolean.FALSE);
                                            cStructMemberList.add(cStructMember);
                                        }
                                    }
                                }
                            }
                        }
                        cStructDeclaration.setCStructMembers(cStructMemberList);
                        cStructDeclarationList.add(cStructDeclaration);
                    }
                }
            }
        }
        return cStructDeclarationList;
    }

2.4结构体实体

@Data
public class CStructDeclaration {

    @ApiModelProperty("id")
    private Long id;

    @ApiModelProperty("名称")
    private String name;

    @ApiModelProperty("结构体参数")
    private List<CStructMember> cStructMembers;

}

@Data
public class CStructMember {

    @ApiModelProperty("id")
    private String id;

    @ApiModelProperty("结构体id")
    private Long structId;

    @ApiModelProperty("字段名称")
    private String name;

    @ApiModelProperty("字段类型")
    private String type;

    @ApiModelProperty("是否为数组。0否 1是")
    private Boolean array;

    @ApiModelProperty("数组长度")
    private Integer arraySize;

}

3.解析接口

    public List<CFunctionDeclaration> getFunctionDeclaration() throws IOException {
        IASTDeclaration[] decs = unit.getDeclarations();

        unit = parseCPP(getContentFile(headerFile));
        ASTNamesVisitor namesVisitor = new ASTNamesVisitor();
        unit.accept(namesVisitor);

        for (IASTName iastName : namesVisitor.getNames()) {
            if (!(iastName.resolveBinding() instanceof ICPPFunction)) {
                continue;
            }
            ICPPFunction function = (ICPPFunction) iastName.resolveBinding();
            List<CFunctionParameter> parameters = new ArrayList<>();
            for (ICPPParameter arg : function.getParameters()) {
                CFunctionParameter param = CFunctionParameter.builder()
                    .type(arg.getType().toString())
                    .rawDeclaration(arg.getType().toString() + " " + arg.getName())
                    .name(arg.getName())
                    .build();
                if (arg.getType() instanceof CPPPointerType) {
                    param.setPointer(true);
                }
                parameters.add(param);
            }
            CFunctionDeclaration funDecl = new CFunctionDeclaration(
                function.getType().getReturnType().toString() + " " + function,
                function.getType().getReturnType().toString(),
                function.getName(),
                parameters
            );
            functions.add(funDecl);
        }

        functions.forEach(fun -> {
            System.out.printf(" Func, declaration: %s, returnType:%s, name:%s,  parameters:\n", fun.getRawDeclaration(),
                fun.getReturnType(), fun.getName());
            fun.getParameters().stream().forEach(p -> {
                System.out.printf("     raw :%s, type:%s, name:%s, isPoint:%b\n", p.getRawDeclaration(), p.getType(),
                    p.getName(), p.isPointer());
            });
        });

        return functions;
    }
@Data
public class CFunctionDeclaration {

    private String returnType;

    private String name;

    private List<CFunctionParameter> parameters;

    private String rawDeclaration;}


@Data
@Builder
public class CFunctionParameter {
    private String type;
    private String name;

    private String rawDeclaration;

    private boolean isPointer;
}
  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值