Dart FFI如何将字符串列表传递给C函数 以tinyfd_saveFileDialog为例
C参数含义解释
char const * const * aFilterPatterns 是C语言里的只读字符串数组,对应注释里提到的{"*.jpg", "*.png"}格式:
- 最内层的
const char *表示每个数组元素都是只读的C字符串 - 外层的
const *表示数组本身的元素指针也是只读的,函数不会修改数组的内容和指向
Dart FFI传参实现步骤
你需要依赖ffi包的工具类处理字符串和内存分配,完整实现流程如下:
1. 先定义FFI函数绑定
import 'dart:ffi'; import 'package:ffi/ffi.dart'; // C侧函数对应的Native类型定义 typedef NativeTinyfdSaveFileDialog = Pointer<Utf8> Function( Pointer<Utf8> aTitle, Pointer<Utf8> aDefaultPathAndFile, Int32 aNumOfFilterPatterns, Pointer<Pointer<Utf8>> aFilterPatterns, Pointer<Utf8> aSingleFilterDescription, ); // Dart侧调用的函数类型定义 typedef DartTinyfdSaveFileDialog = Pointer<Utf8> Function( Pointer<Utf8> aTitle, Pointer<Utf8> aDefaultPathAndFile, int aNumOfFilterPatterns, Pointer<Pointer<Utf8>> aFilterPatterns, Pointer<Utf8> aSingleFilterDescription, ); // 动态库加载和函数绑定示例 // final dylib = DynamicLibrary.open('你的tinyfiledialogs库路径'); // final saveFileDialog = dylib.lookupFunction<NativeTinyfdSaveFileDialog, DartTinyfdSaveFileDialog>('tinyfd_saveFileDialog');
2. 构造字符串数组参数并调用
以传入["*.jpg", "*.png"]过滤规则为例:
void callSaveDialog() { // 使用mallocArena自动管理内存,离开作用域后自动释放所有分配的内存 using((arena) { // 构造过滤规则的字符串数组 const filterPatterns = ["*.jpg", "*.png"]; final filterPatternPtr = arena<Pointer<Utf8>>(filterPatterns.length); for (int i = 0; i < filterPatterns.length; i++) { // 把每个Dart字符串转成C的Utf8指针,存入数组 filterPatternPtr[i] = filterPatterns[i].toNativeUtf8(allocator: arena); } // 调用函数 final resultPtr = saveFileDialog( "保存文件".toNativeUtf8(allocator: arena), "".toNativeUtf8(allocator: arena), // 默认路径留空 filterPatterns.length, filterPatternPtr, "图片文件".toNativeUtf8(allocator: arena), ); // 处理返回的文件路径 if (resultPtr != nullptr) { final filePath = resultPtr.toDartString(); // 这里处理你拿到的文件路径 print("选择的保存路径:$filePath"); } }); }
注意事项
- 如果不需要文件过滤,直接给
aNumOfFilterPatterns传0,aFilterPatterns传nullptr即可 - 上述示例用
using和arena自动管理内存,避免手动释放遗漏导致内存泄漏,如果不用arena,需要手动调用calloc.free释放每一个分配的指针 - tinyfiledialogs返回的字符串指针是库内部的静态内存,不需要你手动释放
内容的提问来源于stack exchange,提问作者xerotolerant
相关产品推荐
相关产品推荐

