【问题标题】:C-style pointer/array casting in Swift?Swift 中的 C 风格指针/数组转换?
【发布时间】:2020-03-09 21:52:28
【问题描述】:

有什么方法可以将不同整数大小的数组转换为另一种数组类型?

例如,在 C 中,我可以这样做:

unsigned char byteArray[] = { 0x1, 0x5, 0xF, 0x3, 0xA5, 0x3, 0x8, 0x8, 0xAB };
unsigned long long *largeArray = (unsigned long long *)(byteArray);

这将使largeArray 等于{ 0x80803A5030F0501, 0x51B76EB7140024AB }

在 Swift 中有没有类似的东西?例如,类似:

let byteArray: [UInt8] = [0x1, 0x5, 0xF, 0x3, 0xA5, 0x3, 0x8, 0x8, 0xAB]
let largeArray = [UInt64](byteArray)

我知道可以以编程方式进行,我只是想知道是否有内置方法,然后再深入研究制作自己的东西来投射它们。

任何帮助将不胜感激!

【问题讨论】:

  • 一般来说,将字符数组转换为具有更高等级的整数类型的数组会由于对齐而导致未定义的行为。
  • 你是对的。我正在为 BigInteger 库执行此操作,并且我希望能够使用任何类型的数组初始化我的 BigNumber 结构。我的结构将数字表示为 UInt64 的数组,但我希望它可以从 UInt32 数组构造。

标签: c arrays swift pointers casting


【解决方案1】:

假设byteArray 有八个字节。你可以这样做:

let byteArray: [UInt8] = [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7]

let value = byteArray.withUnsafeBytes { 
    $0.bindMemory(to: UInt64.self)[0].littleEndian    // or .bigEndian
}

导致:

0x0706050403020100     // or 0x0001020304050607 if you use bigEndian

或者,如果您有足够的字节数容纳多个 UInt64,您可以这样做:

let longByteArray: [UInt8] = [
    0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
    0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
]

let values = longByteArray.withUnsafeBytes {
    $0.bindMemory(to: UInt64.self)
}.map {
    $0.littleEndian       // or .bigEndian
}

导致

[0x0706050403020100, 0x0f0e0d0c0b0a0908] // or [0x0001020304050607, 0x08090a0b0c0d0e0f] if you use bigEndian

【讨论】:

  • 谢谢!这正是我想要的。
猜你喜欢
  • 2014-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多