Swift Xcode6B3 - 字节交换 - 未定义的符号“__OSSwapInt16”

时间:2014-07-21 13:17:03

标签: xcode linker swift

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

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

我错过了什么吗?

3 个答案:

答案 0 :(得分:8)

是的,由于某种原因,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)

两个都有效,结果相同。

答案 1 :(得分:1)

看起来这些是由宏和内联函数组合处理的,所以......我不知道为什么它不会被静态编译成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导入标题的方式是否存在问题......例如,如果导入标题的宏在快速设置中不正确。

答案 2 :(得分:1)

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

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