FFI bindings for function with ***item argument

11 views
Skip to the first unread message

Maarten Boekhold

unread,
28 Nov 2021, 03:13:4028/11/2021
to Dart Misc


I'm trying to write FFI bindings to a C library that has a function that uses ***Struct as one of its parameters:

typedef struct {
    char *name;
    char *value;
} Item;
extern void getItems(Item ***items);

which should be called, and the result used, as:

const Item **items;
getItems(&items);
for (int i = 0; items[i]; i++) {
    Item *item = items[i];
    printf("name: %s, value %s\n", item->name, item->value);
}


I'm very close to making this work, but I'm still stuck at accessing the individual members of Item. When I try to access item->value, the code actually seems to access item->name. Since both name & value are *char, I suspect that item->name and item->value actually resolve just as *item...

class Item extends Struct {
    external Pointer<Utf8> name;
    external Pointer<Utf8> value;
}

late int Function(Pointer<Pointer<Pointer<Item>>>) getItems; 
typedef getItemsNative_t =
    Int32 Function(Pointer<Pointer<Pointer<Item>>>);
getItems = library
    .lookup<NativeFunction<getItemsNative_t ('get_items')
    .asFunction();

Pointer<Pointer<Pointer<Item>>> pppItem = calloc(); getItems(pppItem);

Pointer<Pointer<Item>> ppItem = pppItem.value;
int idx = 0;
Pointer<Item> pItem = ppItem.elementAt(idx).value; // *item
while (pItem != nullptr) {
    Item item = pItem.ref; // IS THIS CORRECT?
    print('name = ${item.name.toDartString()}');
    print('value = ${item.value.toDartString()}');
    pItem = ppItem.elementAt(++idx).value;
}
calloc.free(pppItem);

This almost works. It 'gets to' every Item, except that each member access returns the value for 'name', not 'value', .e.g if the original C code returns:

name = Brad
value = Quarterback
name = John
value = Pitcher

my Dart code returns:

name = Brad
value = Brad
name = John
value = John

I must be doing something wrong at the line with the 'IS THIS CORRECT' comment, but I can't figure out what it is. I've tried various combinations of 'value', 'ref' and 'elementAt()', but the above is the only one that doesn't throw any errors inside my IntelliJ IDE / dart analyzer.

Anybody has any idea/suggestion?

Maarten Boekhold

unread,
28 Nov 2021, 03:26:4528/11/2021
to Dart Misc, Maarten Boekhold

I am so embarrassed. My real code is a bit more complicated than I showed above, and it turns out my test case was incorrect (too much copy/paste).

So, the above all works.

Reply all
Reply to author
Forward
0 new messages