简体   繁体   English

如何在Swift中使用htonl设置整数字节序?

[英]How do I set integer endianness using htonl in Swift?

I'm trying to set integer endianness using htonl() in Swift but the compiler isn't finding the htonl() method. 我正在尝试在Swift中使用htonl()设置整数字节htonl() ,但是编译器没有找到htonl()方法。

I've been using this as my reference: Append NSInteger to NSMutableData 我一直以此为参考: 将NSInteger附加到NSMutableData

Here's my code: 这是我的代码:

import Foundation
import CFNetwork
import CoreFoundation

var data = NSMutableData()
var number : UInt32 = 12
var convertedNumber : UInt32 = htonl(number)
data.appendBytes(&convertedNumber, length: 4)

I've just been running this in a playground. 我刚刚在操场上跑步。 The error is: 错误是:

Use of unresolved identifier 'htonl'

As of Xcode 6, Beta 3, all integer types have a bigEndian method which returns the big-endian representation of the integer and changes the byte order if necessary. 从Xcode 6 Beta 3开始,所有整数类型都有bigEndian方法,该方法返回整数的big-endian表示形式,并在必要时更改字节顺序。 Example: 例:

var data = NSMutableData()
var number : UInt32 = 0x12345678
var convertedNumber = number.bigEndian
data.appendBytes(&convertedNumber, length: 4)
print(data)
// Output: <12345678>

Update for Swift 3: Swift 3更新:

let data = NSMutableData()
let number: UInt32 = 0x12345678
var convertedNumber = number.bigEndian
data.append(&convertedNumber, length: 4)

Or, using the new Data value type: 或者,使用新的Data值类型:

var data = Data()
let number: UInt32 = 0x12345678
var convertedNumber = number.bigEndian
withUnsafePointer(to: &convertedNumber) {
    data.append(UnsafeRawPointer($0).assumingMemoryBound(to: UInt8.self), count: 4)
}

Update : Martin R's answer is the correct answer for current versions of Swift: https://stackoverflow.com/a/24653879/195691 更新 :马丁R的答案是当前版本的Swift的正确答案: https : //stackoverflow.com/a/24653879/195691

-- -

You should use the CFSwapInt32HostToBig() CoreFoundation method, as htonl is likely implemented as a C macro that will not work in swift. 您应该使用CFSwapInt32HostToBig() CoreFoundation方法,因为htonl可能被实现为C宏,该宏无法快速运行。

However, it looks like this doesn't currently work in the Swift playground. 但是,看起来这在Swift操场上目前无法使用。 I'm getting the error Playground execution failed: error: error: Couldn't lookup symbols: __OSSwapInt32 despite the fact that the CoreFoundation documentation now includes method signatures in Swift for its byte swapping methods. 我遇到了错误Playground execution failed: error: error: Couldn't lookup symbols: __OSSwapInt32尽管事实上Playground execution failed: error: error: Couldn't lookup symbols: __OSSwapInt32文档现在在Swift中为其字节交换方法包括了方法签名。

Interestingly, it looks like at least part of <arpa/inet.h> has been ported to swift, as methods like inet_ntoa() and inet_addr() are available to Swift, but the htonl family is not. 有趣的是,它看起来像的至少一部分<arpa/inet.h>已经被移植到迅速,如类似方法inet_ntoa()inet_addr()可用来夫特,但htonl家庭并不。

Instead of using CFSwapInt32HostToBig() as Alex Pretzlav advised you should use 不要像Alex Pretzlav建议的那样使用CFSwapInt32HostToBig()

CFSwapInt32()

instead of 代替

ntonl() and ntohl()

and

CFSwapInt16()

instead of 代替

ntons() and ntohs()

Your code should look like 您的代码应如下所示

import Foundation
import CFNetwork
import CoreFoundation

var data = NSMutableData()
var number : UInt32 = 12
var convertedNumber : UInt32 = CFSwapInt32(number)
data.appendBytes(&convertedNumber, length: 4)

Also there is 也有

CFSwapInt64()

for 8-byted integer swapping. 用于8字节整数交换。

Edit 1 编辑1

Of course you should use these functions only on processors with little endian integers cause functions I provided perform bytes swap anyway. 当然,您应该仅在具有小尾数整数的处理器上使用这些函数,因为我提供的函数仍然会执行字节交换。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM