Dart中的Struct

118 阅读2分钟

在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>();

注意事项:

  1. 数据对齐: 需要确保结构体定义与C中的结构体定义完全一致;
  2. 内存管理: 需要手动管理分配的内存;

进阶(使用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访问结构体指针, 并修改对应字段