Как установить целочисленную endianness с помощью htonl в Swift?
Я пытаюсь установить целочисленную endianness с помощью htonl()
в Swift, но компилятор не находит метод htonl()
.
Я использовал это как мою ссылку: Добавить NSInteger в NSMutableData
Здесь мой код:
import Foundation
import CFNetwork
import CoreFoundation
var data = NSMutableData()
var number : UInt32 = 12
var convertedNumber : UInt32 = htonl(number)
data.appendBytes(&convertedNumber, length: 4)
Я только что запустил это на детской площадке. Ошибка:
Use of unresolved identifier 'htonl'
Ответы
Ответ 1
Обновить: ответ Martin R - правильный ответ для текущих версий Swift: fooobar.com/questions/331555/...
-
Вы должны использовать метод CFSwapInt32HostToBig()
CoreFoundation, поскольку htonl
, скорее всего, реализован как макрос C, который не будет работать в swift.
Однако, похоже, что это не работает в детской площадке Swift. Я получаю сообщение об ошибке Playground execution failed: error: error: Couldn't lookup symbols: __OSSwapInt32
, несмотря на то, что документация CoreFoundation теперь включает в себя сигнатуры методов в Swift для своих методов замены байтов.
Интересно, что по крайней мере часть <arpa/inet.h>
была перенесена на скорость, так как для Swift доступны такие методы, как inet_ntoa()
и inet_addr()
, но в семействе htonl
нет.
Ответ 2
Начиная с Xcode 6, Beta 3, все целые типы имеют метод bigEndian
, который
возвращает большое представление целого числа и изменяет
если необходимо, порядок байтов. Пример:
var data = NSMutableData()
var number : UInt32 = 0x12345678
var convertedNumber = number.bigEndian
data.appendBytes(&convertedNumber, length: 4)
print(data)
// Output: <12345678>
Обновление для Swift 3:
let data = NSMutableData()
let number: UInt32 = 0x12345678
var convertedNumber = number.bigEndian
data.append(&convertedNumber, length: 4)
Или, используя новый тип значения 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)
}
Ответ 3
Вместо использования CFSwapInt32HostToBig(), поскольку Алекс Претцлав посоветовал вам использовать
CFSwapInt32()
вместо
ntonl() and ntohl()
и
CFSwapInt16()
вместо
ntons() and ntohs()
Ваш код должен выглядеть как
import Foundation
import CFNetwork
import CoreFoundation
var data = NSMutableData()
var number : UInt32 = 12
var convertedNumber : UInt32 = CFSwapInt32(number)
data.appendBytes(&convertedNumber, length: 4)
Также есть
CFSwapInt64()
для 8-байтового целочисленного обмена.
Изменить 1
Конечно, вы должны использовать эти функции только для процессоров с небольшим числом целых чисел, вызывающих функции, которые я предоставил, чтобы выполнить байтов в любом случае.