I am porting an application from (Objective-) C to Swift, but I need to use a third-party structure written in C. There are several incompatibilities, such as typedefs, which are interpreted as Int, but must be passed to structure functions like UInts or the like. Therefore, in order to avoid constant casting operations throughout the entire Swift application, I decided to transfer the C header files to Swift, having all types, since they should be in one place for me.
I managed to transfer almost everything and overcome many obstacles, but this one:
The C header defines a structure containing the uint64_t variable among others. This structure is used to pass data to the callback function as a pointer. The callback function takes a void pointer as an argument, and I have to use it in the UnsafeMutablePointer operation for a structure type (or another header structure, if necessary). All casting and memory access works fine as long as I use the original structure from the C header, which was automatically converted by Swift upon import.
Manual structure replication in Swift does not perform byte-fitting.
Let me show you an example of this situation:
Inside the CApiHeader.h file there is something like
typedef struct{ uint32_t var01; uint64_t var02; uint8_t arr[2]; }MyStruct, *MyStructPtr;
In my opinion, there should be an Swift equivalent here
struct MyStruct{ var01: UInt32 var02: UInt64 arr: (UInt8, UInt8) }
Or what should also work is a tuple designation
typealias MyStruct = ( var01: UInt32, var02: UInt64, arr: (UInt8, UInt8) )
This works fine, but not immediately, as soon as the UInt64 type exists.
Ok, so what's going on?
By pointing to one of my own Swift MyStruct implementations, the hole data is shifted by 2 bytes, starting with the UInt64 field. Therefore, in this example, both arr fields are not in the correct position, but inside the UInt64 bit, which should be 64 numbers. Thus, it seams that the UInt64 field has only 48 bits.
This confirms my observation that if I replaced the UIn64 variable with this alternative
struct MyStruct{ var01: UInt32 reserved: UInt16 var02: UInt32 arr: (UInt8, UInt8) }
or this
struct MyStruct{ var01: UInt32 var02: (UInt32, UInt32) arr: (UInt8, UInt8) }
(or equivalent tuple notation), it correctly aligns arr fields. But, as you can easily guess, var02 does not contain directly used data, because it is divided into several address ranges. This is even worse with the first alternative, because it is the seams that Swift fills the gap between the field is reserved and the var02 field with 16 bits is missing / shifted 2 bytes I mentioned above, but they are not available.
So, I did not understand any equivalent conversion of the C structure to Swift.
What exactly happens here and how does Swift actually transform the structure from the C header?
Do you guys have a clue or explanation or even a solution for me?
Update
The C framework has an API function with this signature:
int16_t setHandlers(MessageHandlerProc messageHandler);
MessageHandlerProc is a type of procedure:
typedef void (*messageHandlerProc)(unsigned int id, unsigned int messageType, void *messageArgument);
So setHandlers is a C routine inside a framework that gets a pointer to a callback function. This callback function should provide a void pointer argument that gets cast, for example,
typedef struct { uint16_t revision; uint16_t client; uint16_t cmd; int16_t parameter; int32_t value; uint64_t time; uint8_t stats[8]; uint16_t compoundValueOld; int16_t axis[6]; uint16_t address; uint32_t compoundValueNew; } DeviceState, *DeviceStatePtr;
Swift is smart enough to import messageHandlerProc with agreement syntax (c), so the type of procedure is available directly. On the other hand, it is not possible to use the standard func syntax and the bit function of my callHandler callback for this type. So I used the closure syntax to define the callback function:
let myMessageHandler : MessageHandlerProc = { (deviceID : UInt32, msgType : UInt32, var msgArgPtr : UnsafeMutablePointer<Void>) -> Void in ... }
I converted the above structure to different structures of my original post.
And no! Definition of statistics , since Swift Array does not work. An array in Swift, not equivalent to an array in C, because Swift Array is an extended type. Writing and reading from it with a pointer throws an exception

Only tuples are built into Swift, and you can run back and forth using pointers.
Ok ... this works fine, and my callback function is called whenever data is available.
So, inside myMessageHandler I want to use the saved data inside msgArgPtr , which is a pointer to void and therefore needs to be translated into DeviceState .
let state = (UnsafeMutablePointer<MyDeviceState>(msgArgPtr)).memory
Status Access:
... print(state.time) print(state.stats.0) ...
Whenever I use the automatically created DeviceState Swift Pendant, everything works fine. The temporary variable has a Unix timestamp and the following statistics (available with the tuple syntax !!!) is all where they belong.
Using my manually implemented structure leads to a completely meaningless time stamp value, and the statistics fields move to the left (in the time field) - this is probably why the timestamp value is useless, because it contains bits from the array "array"). Thus, in the last two fields of statistics, I get values from complexValueOld and the first axis field - with all overflows, of course.
While I'm ready to sacrifice the time value and change the UInt64 variable either as a tuple of two UInt32 types, or by changing it to UInt32 type and adding an auxiliary variable of type UInt16 to time , I get an array of stats with the correct alignment.
Have a nice day!: -)
Martin