You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从idevice_event_t结构体的ffi.Pointer<ffi.Char>提取字符串?

Dart FFI解析C结构体字符串报错“分隔符错误/缺失”的解决方案

问题场景

通过Dart FFI接收C回调的idevice_event_t结构体时,能正常获取结构体实例,但解析udid字段时出现“分隔符错误/缺失”,读取到的内容看起来是指针地址而非实际字符串。C端已确认内存无异常,结构体可正常解析。

结构体定义(Dart)

/// Provides information about the occurred event.
final class idevice_event_t extends ffi.Struct {
  /// < The event type.
  @ffi.UnsignedInt()
  external int event;

  /// < The device unique id.
  external ffi.Pointer<ffi.Char> udid;

  /// < The connection type.
  @ffi.UnsignedInt()
  external int conn_type;
}

回调处理代码

void onDeviceChanged(Pointer<idevice_event_t> device, Pointer<Void> data) {
  idevice_event_t event = device.ref;

  log(event.udid.cast<Utf8>().toDartString());
}

问题分析与解决

核心原因

大概率是以下两种情况:

  1. 结构体内存布局不匹配:Dart Struct的默认内存对齐可能和C端不一致,导致udid指针指向错误的内存区域,读取到无效数据(类似指针地址)。
  2. 字符串转换逻辑问题:cast<Utf8>().toDartString()依赖Dart FFI自动识别null终止符,若C端字符串的终止符未被正确识别,会导致读取越界或错误解析。

解决方案

1. 修正结构体内存对齐

在Dart结构体上添加@Packed()注解,匹配C端的内存对齐方式(通常为4字节或8字节,根据C端编译选项调整):

@ffi.Packed(4) // 按C端实际对齐方式设置,比如4字节对齐
final class idevice_event_t extends ffi.Struct {
  @ffi.UnsignedInt()
  external int event;

  external ffi.Pointer<ffi.Char> udid;

  @ffi.UnsignedInt()
  external int conn_type;
}

2. 手动读取C风格字符串

绕过Dart FFI的自动转换,手动读取以null结尾的ASCII字符串,确保正确识别终止符:

// 手动读取C风格null终止字符串
String readCString(Pointer<ffi.Char> ptr) {
  final codeUnits = <int>[];
  int index = 0;
  while (true) {
    final char = ptr.elementAt(index).value;
    if (char == 0) break; // 遇到null终止符停止
    codeUnits.add(char);
    index++;
  }
  return String.fromCharCodes(codeUnits);
}

// 修正后的回调处理
void onDeviceChanged(Pointer<idevice_event_t> device, Pointer<Void> data) {
  idevice_event_t event = device.ref;
  final udid = readCString(event.udid);
  log(udid);
}

验证步骤

  • 优先检查结构体对齐是否正确,内存布局错误会直接导致指针指向无效区域,这是最容易忽略的点。
  • 若对齐没问题,再用手动读取的方式验证字符串是否能正常解析。

内容的提问来源于stack exchange,提问作者Scott Andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:48:09