如何通过dart:ffi不复制数组直接将Dart数组传递给C?
Dart FFI 零复制获取Uint8List指针调用C函数
你可以直接获取Dart Uint8List的底层内存指针,无需复制数据,大幅提升大数组的处理效率,具体实现和注意事项如下:
核心实现代码
利用Uint8List的buffer属性获取底层字节缓冲区,再通过asUint8Pointer()拿到指针,最后转换为C函数需要的const void*类型:
import 'dart:ffi'; import 'dart:typed_data'; void myDartFunc(Uint8List data) { // 获取Uint8List底层的无符号字符指针 final Pointer<UnsignedChar> dataPtr = data.buffer.asUint8Pointer(); // 转换为C函数兼容的const void*类型 callMyCFunc(dataPtr.cast<Void>()); }
关键注意事项
- 同步调用安全:如果C函数是同步执行的,只要
data在myDartFunc执行期间处于作用域内,Dart垃圾回收器就不会回收这块内存,无需额外操作。 - 异步调用需手动保活:如果C函数会在后台线程异步处理数据,必须手动保留对
data的引用(比如将其存储在类成员变量中),直到C函数处理完成并给出回调,否则GC可能提前释放内存,导致野指针错误。 - 切片场景兼容:如果
Uint8List是原数组的切片(比如data.sublist(5, 20)),asUint8Pointer()会指向切片的起始位置,内存依然连续,同样可以直接使用,无需复制。
内容的提问来源于stack exchange,提问作者Haidar
相关产品推荐
相关产品推荐

