Taju Rahman
Taju Rahman

Reputation: 21

Dart/Flutter FFI(Foreign Function Interface): calling a native function with output parameter using FFI in Dart

How to call a native function with output parameter with Dart ffi, since dart doesn't support output parameters. i am looking for an alternative for something like this C# Code

[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);

String PrinterName="Printer1";
IntPtr hPrinter = new IntPtr(0);
OpenPrinter(PrinterName.Normalize(), out hPrinter, IntPtr.Zero)

Upvotes: 2

Views: 1377

Answers (2)

Daco Harkes
Daco Harkes

Reputation: 436

// Allocate some memory for the output to be written to.
final Pointer<Pointer<duckdb_database>> outDb = calloc<Pointer<duckdb_database>>();
// That memory contains a null pointer (we used calloc to zero the memory).
assert(outDb.value == nullptr);

// The native function should populate that memory.
db.open_ext(outDb);
assert(outDb.value != nullptr);

// Our native API probably wants a `duckdb_database*` in the rest of the API, so lets keep that variable.
final Pointer<duckdb_database> db = outDb.value;
// Don't forget to free the memory that we had for the out parameter.
calloc.free(outDb);

// Use `db`...

The SQLite sample in the Dart SDK repo has the same pattern with out parameters.

Upvotes: 6

Kevin Moore
Kevin Moore

Reputation: 6161

I was able to do it by using malloc with zero length from package:ffi

final dbPointer = malloc.allocate<duckdb_database>(0);
print(dbPointer.value); // some initial value
db.open_ext(dbPointer);
print(dbPointer.value); // new value!!

Zero clue if this is "right", but it's working for me!

Upvotes: -1

Related Questions