2

I have a project that currently has a C struct which has been defined as:

typedef struct IDList {

    uint32_t   listID;
    uint32_t   count;
    uint32_t   idArray[];

} __attribute__((packed, aligned(4))) IDList, *IDListPtr;

There is a method in an Objective-C class that returns an IDListPtr to me.

I know I can:

let idListPtr = theIDManager.getIDList()    // ObjC class that returns the struct

let idList = idListPtr.pointee    // Get the IDList struct from the pointer

And I know there are idList.count items in the struct's array, but how do I access that array in Swift?

  • Compare https://stackoverflow.com/q/27061028/1187415 – Martin R Jan 09 '19 at 04:50
  • The problem with that other post is that I have no access to `idListPtr.pointee.idArray` in Swift, it only allows me access to `idListPtr.pointee.listID` and `idListPtr.pointee.count`. So I don't know how to make that solution apply. – Pointy-Haired Boss Jan 09 '19 at 22:55

1 Answers1

1

Zero-length arrays in C are not visible in Swift. A possible workaround is to add a helper function in the bridging header file, which returns the address of the first array item:

static uint32_t * _Nonnull idArrayPtr(const IDListPtr _Nonnull ptr) { return &ptr->idArray[0]; }

Now you can create a “buffer pointer” in Swift which references the variable length array:

let idListPtr = getIDList()
let idArray = UnsafeBufferPointer(start: idArrayPtr(idListPtr), count: Int(idListPtr.pointee.count))
for item in idArray {
    print(item)
}
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382