C style union not imported in Swift bridging header

Hi


I've been reading "Using Swift with Cocoa and Objective-C" on how to import C header files in Swift.


Now I've imported a C header file in Swift using Xcode 6.4. All structs from the C header file have been imported fine using the bridging header except one which is missing a field of type union.


The struct in the C header file looks something like this:


typedef struct Foo {
     int a;
     int b;
     union {
          Astruct aaa;
          AnotherStruct bbb;
     }
} Foo;


The Foo-struct in Swift contains 'a' and 'b' but I cannot see 'aaa' and 'bbb'. So my question is how to I access fields in a union from Swift? Do I need to write a wrapper in either Objective-C or in C?


Here's a link to the actual struct I'm trying to import (TTMessage): https://github.com/BearWare/TeamTalk5/blob/master/TeamTalk_DLL/TeamTalk.h#L2743


Kind regards

-- Bjoern

Accepted Reply

This is taken from the Xcode 6.3 Release Notes:


Swift can now partially import C aggregates containing unions, bitfields, SIMD vector types, and other C language features that are not natively supported in Swift. The unsupported fields will not be accessible from Swift, but C and Objective-C APIs that have arguments and return values of these types can be used in Swift. This includes the Foundation NSDecimal type and the GLKit GLKVector and GLKMatrix types, among others. (15951448)


Unions and bitfields are unsupported in Swift, and this restriction still remains in the latest Xcode 7 beta 6.


Do I need to write a wrapper in either Objective-C or in C?

It seems to be the only solution.



Replies

This is taken from the Xcode 6.3 Release Notes:


Swift can now partially import C aggregates containing unions, bitfields, SIMD vector types, and other C language features that are not natively supported in Swift. The unsupported fields will not be accessible from Swift, but C and Objective-C APIs that have arguments and return values of these types can be used in Swift. This includes the Foundation NSDecimal type and the GLKit GLKVector and GLKMatrix types, among others. (15951448)


Unions and bitfields are unsupported in Swift, and this restriction still remains in the latest Xcode 7 beta 6.


Do I need to write a wrapper in either Objective-C or in C?

It seems to be the only solution.



It is possible to access C unions in Swift 4. When accessing the union, an UnsafeMutablePointer<Type> is returned, the instance can be accessed with the .pointee property of the pointer.


https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html

Unions and Bit Fields are supported since Swift 2.1/Xcode 7.1 .

And an additional feature, unnamed union field is supported in Swift 3.1/Xcode 8.3.


Unions and Bit Fields are supported with computed properties.

So whether they return an UnsafeMutablePointer<Type> or not simply depends on the field is a C-pointer or not.


For example, the struct containing the union member in the OP is imported as follows:


public struct Foo {

    public struct __Unnamed_union___Anonymous_field2 {
        public var aaa: Astruct
        public var bbb: AnotherStruct
        public init(aaa: Astruct)
        public init(bbb: AnotherStruct)
        public init()
    }
    public var a: Int32
    public var b: Int32
    public var __Anonymous_field2: Foo.__Unnamed_union___Anonymous_field2
    public var aaa: Astruct
    public var bbb: AnotherStruct
    public init()
    public init(a: Int32, b: Int32, _ __Anonymous_field2: Foo.__Unnamed_union___Anonymous_field2)
}


When accessing `aaa` or `bbb`, the return type is simpley `Astruct` or `AnotherStruct`, not a pointer.