前言
关于环境和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;
};
void printStudent(const struct Student *student);
struct Student getStudent();
void updateStudent(struct Student *student);
#endif //CDYNAMICDEMO_LIBRARY_H
代码文件(library.c)
#include "library.h"
#include <stdio.h>
void printStudent(const struct Student *student) {
printf("\nthe student's name: %s, age is: %d", student->name, student->age);
}
struct Student getStudent() {
struct Student student;
student.name = "张三";
student.age = 18;
return student;
}
void updateStudent(struct Student *student) {
student->name = "李四";
student->age = 19;
}
2.java代码
package com.dynamic.demo.struct;
import com.dynamic.demo.strings.StringLibrary;
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 StructLibrary extends Library {
StructLibrary INSTANCE = Native.load(Platform.isWindows() ? "libCDynamicDemo" : "", StructLibrary.class);
void printStudent(Student.ByReference reference);
Student.ByValue getStudent();
void updateStudent(Student.ByReference reference);
int sumStudentAge(Student.ByReference reference, int studentCount);
@Getter
@Setter
public static class Student extends Structure {
// 引用用来往C传值
public static class ByReference extends Student implements Structure.ByReference {
}
// 用于接收C返回的值
public static class ByValue extends Student implements Structure.ByValue {
}
// 属性必须是public
public String name;
public int age;
@Override
protected List<String> getFieldOrder() {
// 必须重载,有哪些字段
return Arrays.asList("name", "age");
}
}
public static void main(String[] args) {
// 往dll传值
Student.ByReference reference = new Student.ByReference();
reference.setName("王五");
reference.setAge(20);
StructLibrary.INSTANCE.printStudent(reference);
// 取到dll中的值
Student.ByValue student = StructLibrary.INSTANCE.getStudent();
System.out.println(student.getName());
System.out.println(student.age);
// 由dll去修改, 再次获取便是已经修改后的值了
reference = new Student.ByReference();
StructLibrary.INSTANCE.updateStudent(reference);
System.out.println(reference.getName());
System.out.println(reference.getAge());
}
}
3.查看输出
总结
- 在Java需要定义一个Student类去匹配结构体,这个类需要继承Structure
- Java中传值都是通过ByReference 和 ByValue来实现