Issue
I’m learning how to use dart ffi.
I don’t have much C experience or knowledge.
I’m trying to call a function from a C library(tiny file dialogs).
I can call other functions however I can’t call this one
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" */
{
the main issue is that I don’t understand what
char const* const * a FilterProperties, / *Null or {"*.jpg", "*.png"} */
means.
As far as I was able to get from this issue the C function is asking for an array of strings. The arg aNumberOfFilterPatterns
defines the length of the array.
If that’s the case, how can I prepare the array in dart to pass it to C?
Solution
I was able to do it by making a pointer to pointer to char
like this
/// Define the type like this
typedef SaveFileDialogD = Pointer<Utf8> Function(
Pointer<Pointer<Utf8>> listOfStrings,
);
Look up the function in the dynamic library
SaveFileDialogD saveFileDialog = dylib
.lookupFunction<SaveFileDialogC, SaveFileDialogD>('dylib');
make a function to convert Dart list of string to something more C friendly
/// 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;
}
Finally call the C function like this
Pointer<Utf8> result;
final strListPointer = strListToPointer(["one", "two", "three"]);
result = saveFileDialog(
strListPointer;
);
Answered By – xerotolerant
Answer Checked By – Timothy Miller (FlutterFixes Admin)