2016-09-17 8 views
6

में UnsafeMutablePointer को UnsafeMutableRawPointer कन्वर्ट मैं इस कोड तेज 3

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

कौन सा स्विफ्ट 3. में संकलन नहीं है मैं इसे कैसे ठीक करूं है?

+0

आपका कच्चा सूचक कहां है? ऐसा लगता है कि आप एक निश्चित आकार –

+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 के साथ कुछ भी नहीं करने के लिए। अगर आपके कोड को स्विफ्ट 3 के साथ सी पुस्तकालयों से निपटने की ज़रूरत है, तो आपको void * से निपटना होगा जो स्विफ्ट 3 में UnsafeMutableRawPointer के बराबर है। आपके कोड को इसे एक निश्चित संरचना के रूप में पेश करने की आवश्यकता है। लेकिन किसी भी तरह, तेजी से 3 संकलक कास्टिंग के लिए मेरे लिए मुश्किल हो रहा है। मैंने इसे समझने के लिए कुछ समय बिताया, और मैं अपना कोड साझा करना चाहता हूं कि यह कैसे करें।

कास्टिंग UnsafeMutableRawPointer से UnsafeMutablePointer<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

ऊपर उत्तर के लिए खान्ह गुयेन के लिए धन्यवाद। एक calloc() का उपयोग करने की जरूरत है, देखने में:

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

क्या मैं खोजने गया था कि मैं वास्तव में एक बिटमैप प्राप्त करने के लिए एक ग्राफिक्स आवेदन में "calloc" का उपयोग करने के लिए आवश्यक है। मैंने जो देखा वह यह है कि यदि मॉलोक या स्विफ्ट के आवंटन (क्षमता :) का उपयोग किया गया था, तो आवंटन में यादृच्छिक कचरा था (जैसा कि कोई उम्मीद कर सकता है)। यदि इसे किसी छवि के बिटमैप प्राप्त करने के लिए प्रारंभिक बिंदु के रूप में उपयोग किया गया था, तो छवि की पृष्ठभूमि स्पष्ट होने पर आपको सिम्युलेटर में यादृच्छिक कचरा दिखाई देगा। छवि को चित्रित करते समय वास्तविक डिवाइस स्पष्ट रूप से इसे साफ़ करता है, और सिम्युलेटर स्पष्ट पृष्ठभूमि को नो-ऑप के रूप में मानता है। बिटमैप (स्विफ्ट 3.0) प्राप्त करने के लिए निम्नलिखित UIImage एक्सटेंशन को सक्षम करने में सक्षम:

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 
    } 

}