Swift and comparing C typedef enums

后端 未结 1 2013
说谎
说谎 2020-12-10 08:29

I recently updated to Xcode-Beta4. I\'m working with a c api and there is a typedef enum like this:

typedef enum {
    XML_ELEMENT_NODE=       1,
    XML_ATT         


        
相关标签:
1条回答
  • 2020-12-10 09:16

    The simplest workaround is to find the header and replace the typedef enum with an typedef NS_ENUM(...). The problem with this solution is that everybody in your team has to make the changes.

    The problem is caused by the fact that the C enum is converted into an opaque type (struct?) C.xmlElementType. This type has one single property value of type UInt32. Unfortunately, this property is not public. You can call it from the debugger but using it in compiled code results in an error.

    I managed to do a workaround using reflect but it's a big hack:

    extension xmlElementType : Equatable {
    }
    
    public func ==(lhs: xmlElementType, rhs: xmlElementType) -> Bool {
        var intValue1 = reflect(lhs)[0].1.value as UInt32
        var intValue2 = reflect(rhs)[0].1.value as UInt32
    
        return (intValue1 == intValue2)
    }
    
    var elementType = currentNode.memory.type
    
    if elementType == xmlElementType(1) {
        println("Test")
    }
    

    I think this is a bug. Either the equality should be defined or some way to cast the struct to an integer.

    EDIT:

    Another option is to add an inline conversion function to your bridging header:

    static inline UInt32 xmlElementTypeToInt(xmlElementType type) {
        return (UInt32) type;
    }
    

    And then define equality as

    public func ==(lhs: xmlElementType, rhs: xmlElementType) -> Bool {
        return ((xmlElementTypeToInt(lhs) == xmlElementTypeToInt(rhs))
    }
    

    However, the most simple option I have found is to brutally cast the struct to an UInt32:

    public func ==(lhs: xmlElementType, rhs: xmlElementType) -> Bool {
        var leftValue: UInt32 = reinterpretCast(lhs)
        var rightValue: UInt32 = reinterpretCast(rhs)
    
       return (leftValue == rightValue)
    }
    

    Note this is less reliable because you have to make sure that the struct actually has 32 bytes and it is not an UInt8, for example. The C conversion function is more stable.

    0 讨论(0)
提交回复
热议问题