如何在 dart ffi 中将字符串列表传递给 C

问题描述

我正在学习如何使用 dart ffi。

我没有太多的 C 经验或知识。

我正在尝试从 C 库 (tiny file dialogs) 调用函数

我可以调用其他函数但是我不能调用这个

char * tinyfd_saveFileDialog(
        char const * aTitle,/* NULL or "" */
        char const * aDefaultPathAndFile,/* NULL or "" */
        int aNumOfFilterPatterns,/* 0 */
        char const * const * aFilterPatterns,/* NULL or {"*.jpg","*.png"} */
        char const * aSingleFilterDescription ) /* NULL or "image files" */
{

主要问题是我不明白什么

char const* const * a FilterProperties,/ *Null or {"*.jpg","*.png"} */

意思。

就我能够从 this issue 获得的信息而言,C 函数需要一个字符串数组。 arg aNumberOfFilterPatterns 定义数组的长度。

如果是这样,我如何在 dart 中准备数组以将其传递给 C?

解决方法

我可以通过创建一个指向 char 的指针来做到这一点

喜欢这个

/// Define the type like this
typedef SaveFileDialogD = Pointer<Utf8> Function(
 
  Pointer<Pointer<Utf8>> listOfStrings,);

在动态库中查找函数


SaveFileDialogD saveFileDialog = dylib
    .lookupFunction<SaveFileDialogC,SaveFileDialogD>('dylib');

创建一个函数将字符串的 Dart 列表转换为对 C 更友好的内容

/// Don't forget to run malloc.free with result!
Pointer<Pointer<Utf8>> strListToPointer(List<String> strings) {
  List<Pointer<Utf8>> utf8PointerList =
      strings.map((str) => str.toNativeUtf8()).toList();

  final Pointer<Pointer<Utf8>> pointerPointer =
      malloc.allocate(utf8PointerList.length);

  strings.asMap().forEach((index,utf) {
    pointerPointer[index] = utf8PointerList[index];
  });

  return pointerPointer;
}

最后这样调用C函数

Pointer<Utf8> result;
    final strListPointer = strListToPointer(["one","two","three"]);

    result = saveFileDialog(
       strListPointer;
    );