JNA(十一)结构体中包含结构体

前言

关于环境和dll的生成,不懂的同学可以去查看JNA(一)与JNA(二)的内容
结构体可能比较重要,大多数Java应用与共享库的交互基本是以结构体做为桥梁,这里是结构体中包含结构体

操作

1.C语言代码

头文件(library.h)

#ifndef CDYNAMICDEMO_LIBRARY_H
#define CDYNAMICDEMO_LIBRARY_H

#include <string.h>
#include <stdlib.h>

// 结构体
struct Student {
    char *name;
    int age;
};

// 结构体中包含结构体
typedef struct School {
    // 学生数量
    int num;
    // 学生
    struct Student *students;
} School;

void setSchool(School *school);

School getSchool();

void cleanSchool(School school);

#endif //CDYNAMICDEMO_LIBRARY_H

代码文件(library.c)

#include "library.h"
#include <stdio.h>

void setSchool(School *school) {
    int num = school->num;
    printf("\n学生数量为: %d", num);

    for (int i = 0; i < num; i++) {
        printf("\n学生%d的名字为: %s", i, school->students[i].name);
    }
}

School getSchool() {
    School school;
    school.num = 3;
    school.students = malloc(sizeof(struct Student) * school.num);
    memset(school.students, 0, sizeof(struct Student) * school.num);

    school.students[0].name = "张三";
    school.students[0].age = 10;

    school.students[1].name = "李四";
    school.students[1].age = 12;

    school.students[2].name = "王五";
    school.students[2].age = 17;
    return school;
}

void cleanSchool(School school) {
    free(school.students);

    printf("\n clean school finished.");
}

2.java代码

package com.dynamic.demo.struct;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;
import com.sun.jna.Structure;
import lombok.Getter;
import lombok.Setter;

import java.util.Arrays;
import java.util.List;

public interface StructStructArrayLibrary extends Library {
    StructStructArrayLibrary INSTANCE = Native.load(Platform.isWindows() ? "libCDynamicDemo" : "", StructStructArrayLibrary.class);

    void setSchool(Structure.ByReference school);

    School.ByValue getSchool();

    void cleanSchool(School.ByValue school);

    @Getter
    @Setter
    public static class Student extends Structure {
        // 引用用来往C传值
        public static class ByReference extends StructLibrary.Student implements Structure.ByReference {
        }

        // 用于接收C返回的值
        public static class ByValue extends StructLibrary.Student implements Structure.ByValue {
        }

        // 属性必须是public
        public String name;
        public int age;

        @Override
        protected List<String> getFieldOrder() {
            // 必须重载,有哪些字段
            return Arrays.asList("name", "age");
        }
    }

    @Getter
    @Setter
    static class School extends Structure {
        public static class ByReference extends School implements Structure.ByReference {
        }

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

        public int num;
        public Student.ByReference students;

        @Override
        protected List<String> getFieldOrder() {
            return Arrays.asList("num", "students");
        }
    }

    public static void main(String[] args) {
        School.ByReference school = new School.ByReference();
        school.setNum(5);

        Student.ByReference students = new Student.ByReference();
        school.setStudents(students);

        Student.ByReference[] stuArr = (Student.ByReference[]) students.toArray(school.getNum());
        for (int i = 0; i < stuArr.length; i++) {
            stuArr[i].setName("abc" + i);
            stuArr[i].setAge(20 + i);
        }

        StructStructArrayLibrary.INSTANCE.setSchool(school);

        School.ByValue school1 = StructStructArrayLibrary.INSTANCE.getSchool();
        System.out.println("学生个数: " + school1.getNum());
        Student.ByReference byReference = school1.getStudents();
        Student.ByReference[] array = (Student.ByReference[]) byReference.toArray(school1.getNum());
        for (int i = 0; i < school1.getNum(); i++) {
            System.out.println(array[i].getName() + " -> " + array[i].getAge());
        }

        StructStructArrayLibrary.INSTANCE.cleanSchool(school1);

    }
}

3.查看输出

在这里插入图片描述

总结

  1. 结构体中包含结构体体现在Java上,就是类School中包含Student的引用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值