dart-lang / native

Dart packages related to FFI and native assets bundling.
BSD 3-Clause "New" or "Revised" License
94 stars 33 forks source link

Flexible array members in structs #214

Open arcticfox1919 opened 1 year ago

arcticfox1919 commented 1 year ago

I have a C struct:

typedef struct
{
    int eleSize;
    char* nameDelimiter;
    CNameElement* nameElements[0];
} CNameHierarchy;

Getting an error after generating code with ffigen:

class CNameHierarchy extends ffi.Struct {
  @ffi.Int()
  external int eleSize;

  external ffi.Pointer<ffi.Char> nameDelimiter;

  @ffi.Array.multi([0])
  external ffi.Array<ffi.Pointer<CNameElement>> nameElements;
}

The line @ffi.Array.multi([0]) reports an error: Array dimensions must be positive numbers.

So this tool doesn't support C99's Flexible Array?

liamappelbe commented 1 year ago

@arcticfox1919 Works for me. Maybe this was fixed in a more recent version of dart:ffi. What's your dart --version?

liamappelbe commented 1 year ago

Actually, reading about this a bit more, I think declaring your field like Type name[0]; is undefined behavior. You're supposed to declare flexible array members like Type name[];. If you do this you get a warning from ffigen saying Removed All Struct Members and Flexible array members not supported., and your generated struct will be opaque.

If you own the code containing CNameHierarchy, there are various work arounds. Flexible arrays are syntactic sugar for having a struct that just doesn't have that array member, and then mallocing the struct larger so it has extra space at the end. You can do that manually by just removing nameElements. Alternatively you could make nameElements a CNameElement** and malloc its array separately.

dcharkes commented 1 year ago

So this tool doesn't support C99's Flexible Array?

dart:ffi does not support flexible arrays currently. So package:ffigen can't either. I've filed an issue to possibly add this:

arcticfox1919 commented 1 year ago

My version:

ffigen: ^6.0.1

Dart SDK version: 2.17.6 (stable) (Tue Jul 12 12:54:37 2022 +0200) on "macos_arm64"
arcticfox1919 commented 1 year ago

@liamappelbe It's true that I can use CNameElement** to solve my problem, and I've done so, but I think Flexible Array is useful and would love Dart FFI to support this syntax.