【问题标题】:Swift Xcode6B3 - Byte Swapping - Undefined symbol "__OSSwapInt16"Swift Xcode6B3 - 字节交换 - 未定义符号“__OSSwapInt16”
【发布时间】:2014-07-21 13:17:03
【问题描述】:

我想使用 Swift 方法CFSwapInt16BigToHost,但无法链接。我链接到 CoreFoundation 框架,但每次我收到以下错误:

Undefined symbols for architecture i386:
  "__OSSwapInt16", referenced from:

我错过了什么吗?

【问题讨论】:

    标签: xcode linker swift


    【解决方案1】:

    是的,由于某种原因,CFSwap... 函数不能在 Swift 程序中使用。

    但从 Xcode 6 beta 3 开始,所有整数类型都有 little/bigEndian: 构造函数 和little/bigEndian 属性。 来自UInt16 结构定义:

    /// Creates an integer from its big-endian representation, changing the
    /// byte order if necessary.
    init(bigEndian value: UInt16)
    
    /// Creates an integer from its little-endian representation, changing the
    /// byte order if necessary.
    init(littleEndian value: UInt16)
    
    /// Returns the big-endian representation of the integer, changing the
    /// byte order if necessary.
    var bigEndian: UInt16 { get }
    
    /// Returns the little-endian representation of the integer, changing the
    /// byte order if necessary.
    var littleEndian: UInt16 { get }
    

    例子:

    // Data buffer containing the number 1 in 16-bit, big-endian order:
    var bytes : [UInt8] = [ 0x00, 0x01]
    let data = NSData(bytes: &bytes, length: bytes.count)
    
    // Read data buffer into integer variable:
    var i16be : UInt16 = 0
    data.getBytes(&i16be, length: sizeofValue(i16be))
    println(i16be) // Output: 256
    
    // Convert from big-endian to host byte-order:
    let i16 = UInt16(bigEndian: i16be)
    println(i16) // Output: 1
    

    更新:从 Xcode 6.1.1 开始,CFSwap... 函数在 Swift 中可用,所以

    let i16 = CFSwapInt16BigToHost(bigEndian: i16be)
    let i16 = UInt16(bigEndian: i16be)
    

    两者工作,结果相同。

    【讨论】:

    • 我的帖子中遗漏了一个精度。我想将字节从 bigendian 交换到主机!
    • @yageek: let x = UInt16(bigEndian: y)x = CFSwapInt16BigToHost(y) 一样。这就是你要找的吗?
    【解决方案2】:

    看起来这些是通过宏和内联函数的组合处理的,所以...我不知道为什么它还没有被静态编译到 CF 版本中:

    一般要解决这种依赖之谜,你可以只搜索没有前缀下划线的裸函数名,然后找出应该从哪里链接

    #define OSSwapInt16(x)  __DARWIN_OSSwapInt16(x)
    

    然后

    #define __DARWIN_OSSwapInt16(x) \
    ((__uint16_t)(__builtin_constant_p(x) ? __DARWIN_OSSwapConstInt16(x) : _OSSwapInt16(x)))
    

    然后

    __DARWIN_OS_INLINE
    __uint16_t
    _OSSwapInt16(
        __uint16_t        _data
    )
    {
        return ((__uint16_t)((_data << 8) | (_data >> 8)));
    }
    

    我知道这不是一个真正的答案,但它太大了,无法发表评论, 我认为您可能需要找出 swift 导入标头的方式是否存在问题...例如,在 swift 设置中导入标头的宏不正确。

    【讨论】:

      【解决方案3】:

      正如其他答案所指出的,__OSSwapInt16 交换方法似乎不在 CFByte 框架的 swift 标头中。我认为快速的替代方案是:

      var dataLength: UInt16 = 24
      var swapped = UInt16(dataLength).byteSwapped 
      

      【讨论】:

        猜你喜欢
        • 2015-02-08
        • 1970-01-01
        • 2018-02-13
        • 2014-11-07
        • 2021-03-12
        • 1970-01-01
        • 2011-10-21
        • 1970-01-01
        • 2015-04-11
        相关资源
        最近更新 更多