2016-09-17 150 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 
    } 

}