前言
关于环境和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.查看输出
总结
- 结构体中包含结构体体现在Java上,就是类School中包含Student的引用