How to make C Struct with dispatch_queue_t member accessible in Swift

I am trying to use a C API in Swift. (Plain C, no Obj-C, no C++).

It is a C struct with a set of functions that take the struct passed in by reference.

The struct is using GCD to get its work done, so it has a dispatch_queue_t as a member.

If I remove the dispatch_queue_t and dispatch_source_t from the struct, the NeatStruct type is accessible from Swift. (So the bridging header is set up correctly.)

Is there something I can do to make the C struct available to Swift with members using libdispatch types?

This is with Xcode 11.1 on macOS 10.14.6, so it is Swift 5.

Thank you for any assistance.

The API is something like the following:

typedef struct NeatStruct {
     dispatch_queue_t queue;
     dispatch_source_t timer;
     int someValue;
     int anotherValue;
     void *neatBuffer
} NeatStruct;

Swift doesn't yet handle strong references in structs (rdar://problem/49400746). To work around this, you can explicitly add __unsafe_unretained to the queue and timer fields to have them be Unmanaged instead. Sorry for the inconvenience!

1 Like

Thanks - and just to clarify - using __unsafe_unretained is just letting Swift know it is not responsible for the memory management of those items.

The C code already has a setup function that creates the dispatch queue and a teardown method that releases it.

I wish it were just Swift [in this case], but it will also affect any ARC Objective-C code that uses the struct. If you decide you really want to conditionalize this, you can test for the presence of the __swift__ macro, which is only defined by the Swift compiler when importing (Obj)C code.

Okay, yes that makes sense. This code is just C, no Obj-C and no ARC, so that should be fine for my purposes. Thank you again!

1 Like