在dart中是没有结构体的定义的, 我们需要通过ffi来引入Struct, Struct经常用于与C或者CPP通信, 用于对数据类型(结构体类型)的对齐. 他的定义跟使用十分简单:
定义:
final class TestS extends Struct {
// 通过注解的方式定义成员类型, 必须严格按照原c中的大小类型定义
@Uint8()
external int status;
@Uint16()
external int motor0;
@Uint16()
external int motor1;
@Uint16()
external int motor2;
@Uint16()
external int motor3;
}
使用:
// 这里示例主动分配一块内存, 但通常是通过so,dll等外部函数来接收这个结构体
static final Pointer<TestS> _con = calloc<SDL2Control>();
注意事项:
- 数据对齐: 需要确保结构体定义与C中的结构体定义完全一致;
- 内存管理: 需要手动管理分配的内存;
进阶(使用extension扩展结构体的方法和属性)
// ref 允许你通过指针访问和修改结构体或联合体的字段
extension TestSEx on Pointer<TestS> {
void init() {
ref
..status = 0
..motor0 = 0
..motor1 = 0
..motor2 = 0
..motor3 = 0;
}
set status(int val) => ref.status = val;
int get status => ref.status;
int get motor0 => ref.motor0;
int get motor1 => ref.motor1;
int get motor2 => ref.motor2;
int get motor3 => ref.motor3;
set motor0(int val) => ref.motor0 = val.abs() > 65535 ? 65535 : val;
set motor1(int val) => ref.motor1 = val.abs() > 65535 ? 65535 : val;
set motor2(int val) => ref.motor2 = val.abs() > 65535 ? 65535 : val;
set motor3(int val) => ref.motor3 = val.abs() > 65535 ? 65535 : val;
void dispose() {
calloc.free(this);
}
}
// 这里示例主动分配一块内存, 但通常是通过so,dll等外部函数来接收这个结构体
static final Pointer<TestS> _con = calloc<SDL2Control>();
_con.status = 1;
我们通过extension关键字就可以拓展结构体的方法或属性, 通过ref访问结构体指针, 并修改对应字段