将 C 指针转换为 Swift 3

Converting C pointers to Swift 3

我有代码:

let data = Data(bytes: UnsafePointer<UInt8>(audioBuffer.mData), count: Int(bufferSize))

let u16 = UnsafePointer<Int32>(audioBuffer.mData).pointee

两者都在 Swift 2.3 中有效,但在 Swift 3 中无效。我如何转换它们以使它们等效? (为什么?)

检查the latest reference of Data.init(bytes:count:)

参数bytes的类型为UnsafeRawPointer,接受UnsafeMutableRawPointerAudioBuffer.mData 的类型是 UnsafeMutableRawPointer?。您无需使用初始化程序进行转换。

let data = Data(bytes: audioBuffer.mData!, count: Int(bufferSize))

(您只需要显式解包 mData,因为它作为可空类型导入,UnsafeMutableRawPointer?,但您需要传递非零 UnsafeRawPointer(或 UnsafeMutableRawPointer).


第二个例子,你最好看看UnsafeMutableRawPointer都有哪些方法。你可以找到 load(fromByteOffset:as:) 方法,并可以像这样使用它。

let i32 = audioBuffer.mData!.load(as: Int32.self)

`加载(

我不能说我理解得很好,nor have I read the document,但看起来 swift3 指针转换的范围是为了避免或限制别名,所以你不能 (很容易)对同一块内存有两种不同的看法,或者至少不会持续很长时间。这意味着您必须复制演员表数据或在演员表回调中做任何您需要做的事情。

为什么要消除锯齿?我想这会让编译器更快乐。

对于Data

// [NS]Data. probably copying the data 
Data(bytes: audioBuffer.mData!, count: Int(audioBuffer.mDataByteSize))

对于数值数组:

// cast the data to Int32s & (optionally) copy the data out
let umpInt32 = audioBuffer.mData!.assumingMemoryBound(to: Int32.self)

let frameCount = Int(audioBuffer.mDataByteSize/4)
var u32 = [Int32](repeating: 0, count: frameCount)

// copy data from buffer
u32.withUnsafeMutableBufferPointer {
    [=11=].baseAddress!.initialize(from: umpInt32, count: frameCount)
}

p.s。您的代码有些混乱。 u16 应该是 Int32 的数组吗?或者 UInt16s?或者别的什么?

要从 Swift3 中的音频单元回调缓冲区读取 16 位音频样本,我使用:

let bufferPointer = UnsafeMutableRawPointer(mBuffers.mData)
if var bptr = bufferPointer {
  for i in 0..<(Int(frameCount)) {
    let oneSampleI16 = bptr.assumingMemoryBound(to: Int16.self).pointee
    // do something with the audio sample
    bptr += 1
  }
}

其余的音频会话和音频单元代码在这个要点中:https://gist.github.com/hotpaw2/630a466cc830e3d129b9