2016-09-17 173 views
6

轉換UnsafeMutableRawPointer到UnsafeMutablePointer 我有這樣的代碼 在迅速3

let grayData = UnsafeMutablePointer<UInt8>(other: malloc(width * height * sizeof(UInt8))) 

這並不在斯威夫特3.編譯如何解決這個問題?

+0

你的原始指針在哪裏?看起來像你初始化一個特定大小的'UnsafeMutablePointer ' –

+0

我的壞,'UInt8',而不是'UInt32' –

回答

7

在你的情況,你最好使用allocate(capacity:)方法。

let grayData = UnsafeMutablePointer<UInt8>.allocate(capacity: width * height) 
1

發現

let grayData = malloc(width * height * MemoryLayout<UInt8>.size)!.assumingMemoryBound(to: UInt8.self) 
24

我遇到了類似的問題,但與malloc沒有任何關係。如果你的代碼需要用Swift 3來處理C庫,那麼你必須在Swift 3中處理void *這相當於UnsafeMutableRawPointer。你的代碼需要把它看作一個特定的結構。但不知何故,swift 3編譯器正在對我進行強制轉換。我花了一些時間想出來,我喜歡分享我的代碼如何做到這一點。

以下是演示UnsafeMutableRawPointerUnsafeMutablePointer<T>的代碼,修改其指針,並確保原始Context已更新。

struct Context { 
    var city = "Tokyo" 
} 

var context: Context = Context() 
let rawPtr = UnsafeMutableRawPointer(&context) 
let opaquePtr = OpaquePointer(rawPtr) 
let contextPtr = UnsafeMutablePointer<Context>(opaquePtr) 

context.city // "Tokyo" 
contextPtr.pointee.city = "New York" 
context.city // "New York" 
0

感謝上面的答案Khanh Nguyen。如果一個人需要使用釋放calloc(),看看:

let imageData = calloc(width * height, MemoryLayout<UInt32>.size).assumingMemoryBound(to: UInt32.self) 

我是找到的是,我需要實際使用「釋放calloc」在圖形應用程序來獲得一個位圖。我看到的是,如果使用malloc或Swift的分配(容量:),分配有隨機垃圾(正如人們所期望的那樣)。如果這被用作獲取圖像的位圖的起點,那麼如果圖像的背景清晰,則會在模擬器中看到隨機垃圾。真正的設備在繪製圖像時顯然清除了這一點,模擬器將清晰的背景視爲無操作。能夠然後使下面的UIImage擴展得到一個位圖(Swift 3.0):

extension UIImage { 

    func unSafeBitmapData() -> UnsafeMutablePointer<UInt32>? { 
     guard let cgImage = self.cgImage else { return nil } 

     let width = Int(self.size.width) 
     let height = Int(self.size.height) 
     let bitsPerComponent = 8 

     let bytesPerPixel = 4 
     let bytesPerRow = width * bytesPerPixel 
     let maxPix = width * height 

     let imageData = calloc(maxPix, MemoryLayout<UInt32>.size).assumingMemoryBound(to: UInt32.self) 
     let colorSpace = CGColorSpaceCreateDeviceRGB() 

     var bitmapInfo: UInt32 = CGBitmapInfo.byteOrder32Big.rawValue 
     bitmapInfo |= CGImageAlphaInfo.premultipliedLast.rawValue & CGBitmapInfo.alphaInfoMask.rawValue 
     guard let imageContext = CGContext(data: imageData, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo) else { return nil } 
     imageContext.draw(cgImage, in: CGRect(origin: CGPoint.zero, size: self.size)) 

     return imageData 
    } 

}