前言
关于环境和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;
};
// 注意这里的students是只带一个星号的
void getMultiplyStudents(struct Student *students, int *len);
#endif //CDYNAMICDEMO_LIBRARY_H
代码文件(library.c)
#include "library.h"
#include <stdio.h>
void getMultiplyStudents(struct Student *students, int *len) {
*len = 3;
students[0].name = "张三";
students[0].age = 20;
students[1].name = "李四";
students[1].age = 30;
students[2].name = "王五";
students[2].age = 40;
}
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 StructArrayOtherLibrary extends Library {
StructArrayOtherLibrary INSTANCE = Native.load(Platform.isWindows() ? "libCDynamicDemo" : "", StructArrayOtherLibrary.class);
void getMultiplyStudents(Student[] byReference, IntByReference reference);
@Getter
@Setter
@NoArgsConstructor
public static class Student extends Structure {
// 属性必须是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) {
int count = 5;
IntByReference intByReference = new IntByReference();
Student[] byReference = new Student[count];
StructArrayOtherLibrary.INSTANCE.getMultiplyStudents(byReference, intByReference);
count = intByReference.getValue();
System.out.println("接收到的学生数量为: " + count);
for (int i = 0; i < count; i++) {
System.out.println(byReference[i].getName());
}
}
}
3.查看输出
总结
- 仔细观察,c语言中定义一个结构体指针就可以了(单个星号)
- 我们在java代码中定义一个数组,数组的长度可以更长,通过返回的参数取拿到实际的长度循环,实际情况我们也可以通过返回值获取长度,约定好就行