将UnsafeMutableRawPointer转换为UnsafeMutablePointer,在swift 3中。

时间:2023-01-12 20:39:38

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?

它不能在Swift 3中编译。我怎么解决这个问题?

4 个解决方案

#1


7  

In your case, you'd better use allocate(capacity:) method.

在您的情况下,您最好使用分配(容量:)方法。

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

#2


24  

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.

我遇到了类似的问题,但与malloc无关。如果您的代码需要与Swift 3处理C库,则必须处理void *,它相当于Swift 3中的UnsafeMutableRawPointer。您的代码需要将其视为一个特定的结构。但不知何故,斯威夫特3号的编译器对我来说太难了。我花了一些时间来解决这个问题,我喜欢分享我的代码如何做到这一点。

Here is the code to demonstrate casting UnsafeMutableRawPointer to UnsafeMutablePointer<T>, modify its pointee, and make sure the original Context is updated.

下面是演示如何将UnsafeMutableRawPointer转换为UnsafeMutablePointer ,修改它的pointee,并确保原始上下文被更新的代码。

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"

#3


1  

Found it

发现它

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

#4


0  

Thanks to Khanh Nguyen for answer above. If one needs to use calloc(), look at:

感谢Khanh Nguyen的回答。如果需要使用calloc(),请查看:

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):

我发现,我需要在图形应用程序中实际使用“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
    }

}

#1


7  

In your case, you'd better use allocate(capacity:) method.

在您的情况下,您最好使用分配(容量:)方法。

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

#2


24  

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.

我遇到了类似的问题,但与malloc无关。如果您的代码需要与Swift 3处理C库,则必须处理void *,它相当于Swift 3中的UnsafeMutableRawPointer。您的代码需要将其视为一个特定的结构。但不知何故,斯威夫特3号的编译器对我来说太难了。我花了一些时间来解决这个问题,我喜欢分享我的代码如何做到这一点。

Here is the code to demonstrate casting UnsafeMutableRawPointer to UnsafeMutablePointer<T>, modify its pointee, and make sure the original Context is updated.

下面是演示如何将UnsafeMutableRawPointer转换为UnsafeMutablePointer ,修改它的pointee,并确保原始上下文被更新的代码。

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"

#3


1  

Found it

发现它

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

#4


0  

Thanks to Khanh Nguyen for answer above. If one needs to use calloc(), look at:

感谢Khanh Nguyen的回答。如果需要使用calloc(),请查看:

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):

我发现,我需要在图形应用程序中实际使用“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
    }

}