What is UnsafeMutablePointer<Void>? How to modify the underlying memory?

為{幸葍}努か 提交于 2019-12-18 11:57:27

问题


I am trying to work with SpriteKit's SKMutableTexture class but I don't know how to work with UnsafeMutablePointer< Void >. I have a vague idea that it is a pointer to a succession of byte data in memory. But how can I update it? What would this actually look like in code?

Edit

Here is a basic code sample to work with. How would I get this to do something as simple as create a red square on the screen?

    let tex = SKMutableTexture(size: CGSize(width: 10, height: 10))
    tex.modifyPixelDataWithBlock { (ptr:UnsafeMutablePointer<Void>, n:UInt) -> Void in

        /* ??? */

    }

回答1:


From the docs for SKMutableTexture.modifyPixelDataWithBlock:

The texture bytes are assumed to be stored as tightly packed 32 bpp, 8bpc (unsigned integer) RGBA pixel data. The color components you provide should have already been multiplied by the alpha value.

So, while you’re given a void*, the underlying data is in the form of a stream of 4x8 bits.

You could manipulate such a structure like so:

// struct of 4 bytes
struct RGBA {
    var r: UInt8
    var g: UInt8
    var b: UInt8
    var a: UInt8
}

let tex = SKMutableTexture(size: CGSize(width: 10, height: 10))
tex.modifyPixelDataWithBlock { voidptr, len in
    // convert the void pointer into a pointer to your struct
    let rgbaptr = UnsafeMutablePointer<RGBA>(voidptr)

    // next, create a collection-like structure from that pointer
    // (this second part isn’t necessary but can be nicer to work with)
    // note the length you supply to create the buffer is the number of 
    // RGBA structs, so you need to convert the supplied length accordingly...
    let pixels = UnsafeMutableBufferPointer(start: rgbaptr, count: Int(len / sizeof(RGBA))

    // now, you can manipulate the pixels buffer like any other mutable collection type
    for i in indices(pixels) {
        pixels[i].r = 0x00
        pixels[i].g = 0xff
        pixels[i].b = 0x00
        pixels[i].a = 0x20
    }
}



回答2:


UnsafeMutablePointer<Void> is the Swift equivalent of void* - a pointer to anything at all. You can access the underlying memory as its memory property. Typically, if you know what the underlying type is, you'll coerce to a pointer to that type first. You can then use subscripting to reach a particular "slot" in memory.

For example, if the data is really a sequence of UInt8 values, you could say:

let buffer = UnsafeMutablePointer<UInt8>(ptr)

You can now access the individual UIInt8 values as buffer[0], buffer[1], and so forth.



来源:https://stackoverflow.com/questions/28398677/what-is-unsafemutablepointervoid-how-to-modify-the-underlying-memory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!