【发布时间】:2014-07-21 13:17:03
【问题描述】:
我想使用 Swift 方法CFSwapInt16BigToHost,但无法链接。我链接到 CoreFoundation 框架,但每次我收到以下错误:
Undefined symbols for architecture i386:
"__OSSwapInt16", referenced from:
我错过了什么吗?
【问题讨论】:
我想使用 Swift 方法CFSwapInt16BigToHost,但无法链接。我链接到 CoreFoundation 框架,但每次我收到以下错误:
Undefined symbols for architecture i386:
"__OSSwapInt16", referenced from:
我错过了什么吗?
【问题讨论】:
是的,由于某种原因,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)
两者工作,结果相同。
【讨论】:
let x = UInt16(bigEndian: y) 和 x = CFSwapInt16BigToHost(y) 一样。这就是你要找的吗?
看起来这些是通过宏和内联函数的组合处理的,所以...我不知道为什么它还没有被静态编译到 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 设置中导入标头的宏不正确。
【讨论】:
正如其他答案所指出的,__OSSwapInt16 交换方法似乎不在 CFByte 框架的 swift 标头中。我认为快速的替代方案是:
var dataLength: UInt16 = 24
var swapped = UInt16(dataLength).byteSwapped
【讨论】: