前言
关于环境和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;
};
// 结构体数组
int sumStudentAge(const struct Student *students, int studentCount);
void getMultiStudents(struct Student **students, int *len);
void cleanStudents(struct Student *students);
#endif //CDYNAMICDEMO_LIBRARY_H
代码文件(library.c)
#include "library.h"
#include <stdio.h>
int sumStudentAge(const struct Student *students, int studentCount) {
int sum = 0;
int i = 0;
for (i = 0; i < studentCount; i++) {
sum += students[i].age;
}
return sum;
}
void getMultiStudents(struct Student **students, int *len) {
*len = 3;
*students = malloc(sizeof(struct Student) * (*len));
memset(*students, 0, sizeof(struct Student) * 3);
(*students)[0].name = "张三";
(*students)[0].age = 20;
(*students)[1].name = "李四";
(*students)[1].age = 30;
(*students)[2].name = "王五";
(*students)[2].age = 40;
}
void cleanStudents(struct Student *students) {
printf("\n清理结构体数组内存!");
free(students);
}
2.java代码
package com.dynamic.demo.struct;
import com.sun.jna.*;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.Arrays;
import java.util.List;
public interface StructArrayLibrary extends Library {
StructArrayLibrary INSTANCE = Native.load(Platform.isWindows() ? "libCDynamicDemo" : "", StructArrayLibrary.class);
int sumStudentAge(Student.ByReference reference, int studentCount);
void getMultiStudents(PointerByReference pointer, IntByReference reference);
void cleanStudents(Pointer pointer);
@Getter
@Setter
@NoArgsConstructor
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;
// 这里需要加一个入参是指针的构造
public Student(Pointer pointer) {
super(pointer);
}
@Override
protected List<String> getFieldOrder() {
// 必须重载,有哪些字段
return Arrays.asList("name", "age");
}
}
public static void main(String[] args) {
Student.ByReference reference = new Student.ByReference();
int count = 5;
Student.ByReference[] array = (Student.ByReference[]) reference.toArray(5);
for (int i = 0; i < count; i++) {
array[i].setAge(10 + i);
}
int age = StructArrayLibrary.INSTANCE.sumStudentAge(reference, count);
System.out.println("所有学生年龄之和为: " + age);
PointerByReference pointerByReference = new PointerByReference();
IntByReference intByReference = new IntByReference();
StructArrayLibrary.INSTANCE.getMultiStudents(pointerByReference, intByReference);
count = intByReference.getValue();
System.out.println("接收到的学生数量为: " + count);
Pointer pointer = pointerByReference.getValue();
Student studentRef = new Student(pointer);
// 这句不能少,否则有可能读到的数据不完整
studentRef.read();
Student[] students = (Student[]) studentRef.toArray(count);
for (int i = 0; i < count; i++) {
System.out.println("name: " + students[i].getName());
}
StructArrayLibrary.INSTANCE.cleanStudents(pointer);
}
}
3.查看输出

总结
- Student类中需要增加一个指针入参的构造
- 引用可以通过toArray转化成数组,同时数组中的元素应该已经初始化了,因为可以直接调用而不报空指针异常
- 如果输出的数据存在null的情况,可以尝试调用read方法
结构体数组&spm=1001.2101.3001.5002&articleId=134132692&d=1&t=3&u=05e320f6c39b4fd3bb6ea474d05c4402)
2346

被折叠的 条评论
为什么被折叠?



