dart ffi: Pointer<Void> as function argument

646 views
Skip to first unread message

Maarten Boekhold

unread,
Nov 29, 2021, 3:03:26 AM11/29/21
to Dart Misc
First of all, apologies if the below question shows up twice. I posted this same question earlier today, but it doesn't seem to show up. I'm not sure if that's due to moderation, or if something went wrong on my end.

I'm having big trouble creating FFI bindings for the following C function:

typedef Handle void;
int getDeviceHandle(char *deviceName, Handle *handle);

which is called in C as follows:

Handle handle;
int res = getDeviceHandle("myDevice", &handle);

I'm trying in Dart with variations of:

typedef Handle = Void;

late int Function(
    List<Utf8> deviceName,
    Pointer<Void> handle
) getDeviceHandle;

typedef getDeviceHandle_native_t = Int32 Function(
    List<Utf8> deviceName,
    Pointer<Void> handle
);

// "library" is the opened library
getDeviceHandle = library
    .lookup<NativeFunction<getDeviceHandle_native_t>>('getDeviceHandle')
    .asFunction();

// Now to call getDeviceHandle()
Pointer<Handle> handlePtr = calloc(); // fails at runtime here
String deviceName = "myDevice";
int res = getDeviceHandle(
    deviceName.toNativeUtf8(),
    handlePtr
);
handle = handlePtr.value; // don't know how to extract the actual Handle object.
                          // There is no 'value' property (or 'ref')

Can anybody help me to get this to work? I've searched a lot through packages on pub.dev that use dart:ffi in the hope of finding a similar situation, but haven't been able to find anything that worked for me.

Daco Harkes

unread,
Nov 29, 2021, 5:10:42 AM11/29/21
to mi...@dartlang.org
Dear Maarten,

To clarify, are you using Handle as in the Dart_Handle from dart_api.h? Or is Handle just a name and could it have been called DeviceHandle as well?

Handle from dart_api.h
Currently FFI trampolines and callbacks convert Dart_Handle on the C side to Object on the Dart side. (The reasoning: why have a handle in Dart if you can have a normal pointer instead?)

To use a Dart_Handle:

// no typedef from Handle to void

late Object Function(
    List<Utf8> deviceName,
    Pointer<Int32> returnStatusCode,
) getDeviceHandle;

typedef getDeviceHandle_native_t = Handle Function(
    List<Utf8> deviceName,
    Pointer<Int32> returnStatusCode,
);


By value structs
If it's just a typedef.

One can't dereference a void* in C, nor can one get the value of a Pointer<Void> in Dart.

If you know the structure of the struct then define it as struct

class DeviceHandle extends Struct {
  external int myField;

  // more fields
}

Then a Pointer<DeviceHandle> can be dereferenced by .ref to get a DeviceHandle which gives access to the myField.

Kind regards,

 •  Daco Harkes
 •  Software Engineer
 •  dacoh...@google.com 


--
For more ways to connect visit https://dart.dev/community
---
You received this message because you are subscribed to the Google Groups "Dart Misc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to misc+uns...@dartlang.org.
To view this discussion on the web visit https://groups.google.com/a/dartlang.org/d/msgid/misc/e06b9434-7196-4d7d-b39c-ac95b64d0566n%40dartlang.org.

Maarten Boekhold

unread,
Nov 30, 2021, 1:20:10 AM11/30/21
to Dart Misc, dacoh...@google.com
Hi Daco, your response prompted me to compose a very detailed description of what I'm (trying) to do, which had me jump into the source code of the library I'm trying to create bindings for. This proved very useful as it led me to discover my mistake: I need to deal with a **void, not *void. So in Dart, "Pointer<Pointer<Void>> handle = calloc();". I have much progressed now. Thanks for responding to my query,

Maarten

Reply all
Reply to author
Forward
0 new messages