Reputation: 11134
I have this code
let grayData = UnsafeMutablePointer<UInt8>(other: malloc(width * height * sizeof(UInt8)))
Which doesn't compile in Swift 3. How do I fix this?
Upvotes: 12
Views: 12783
Reputation: 60081
I believe in Swift 5, we can do so using (assuming T is UInt8
)
let unsafeMutablePointer
= unsafeMutableRawPointer.bindMemory(to: UInt8.self, capacity: capacity)
Upvotes: 1
Reputation: 1925
Thanks to Khanh Nguyen for answer above. If one needs to use calloc(), look at:
let imageData = calloc(width * height, MemoryLayout<UInt32>.size).assumingMemoryBound(to: UInt32.self)
What I was finding is that I needed to actually use "calloc" in a graphics application to get a bitmap. What I saw is that if malloc or Swift's allocate(capacity:) were used, that the allocation had random garbage (as one might expect). If this was used as the starting point for getting a bitmap of an image, you would see the random garbage in the simulator if the image's background was clear. Real device apparently clears this when drawing the image, and simulator treats clear background as a no-op. Able to then make the following UIImage extension to get a bitmap (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
}
}
Upvotes: 1
Reputation: 1637
I ran into a similar problem, but nothing to do with malloc
. If your code needs to deal with C libraries with Swift 3, you have to deal with void *
which is equivalent to UnsafeMutableRawPointer
in Swift 3. Your code needs to treat it as a certain structure. But somehow, swift 3 compiler is being hard on me for casting. I spent some time to figured it out, and I like to share my code how to do that.
Here is the code to demonstrate casting UnsafeMutableRawPointer
to UnsafeMutablePointer<T>
, modify its pointee, and make sure the original Context
is updated.
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"
Upvotes: 34
Reputation: 47876
In your case, you'd better use allocate(capacity:)
method.
let grayData = UnsafeMutablePointer<UInt8>.allocate(capacity: width * height)
Upvotes: 11
Reputation: 11134
Found it
let grayData = malloc(width * height * MemoryLayout<UInt8>.size)!.assumingMemoryBound(to: UInt8.self)
Upvotes: 2