什么是 UnsafeMutablePointer<Void>?如何修改底层内存?
What is UnsafeMutablePointer<Void>? How to modify the underlying memory?
我正在尝试使用 SpriteKit 的 SKMutableTexture
class,但我不知道如何使用 UnsafeMutablePointer< Void >
。我有一个模糊的想法,它是指向内存中一连串字节数据的指针。但是我该如何更新呢?这在代码中实际上是什么样的?
编辑
这是一个可以使用的基本代码示例。我怎样才能让它做一些像在屏幕上创建一个红色方块这样简单的事情?
let tex = SKMutableTexture(size: CGSize(width: 10, height: 10))
tex.modifyPixelDataWithBlock { (ptr:UnsafeMutablePointer<Void>, n:UInt) -> Void in
/* ??? */
}
UnsafeMutablePointer<Void>
是 Swift 等价于 void*
- 指向任何东西的指针。您可以访问底层内存作为其 memory
属性。通常,如果您知道底层类型是什么,您将首先强制指向该类型的指针。然后,您可以使用下标到达内存中的特定 "slot"。
例如,如果数据确实是一个 UInt8 值序列,您可以说:
let buffer = UnsafeMutablePointer<UInt8>(ptr)
您现在可以通过 buffer[0]
、buffer[1]
等访问单独的 UIInt8 值。
来自 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.
因此,当您获得 void*
时,基础数据采用 4x8 位流的形式。
您可以像这样操作这样的结构:
// 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
}
}
我正在尝试使用 SpriteKit 的 SKMutableTexture
class,但我不知道如何使用 UnsafeMutablePointer< Void >
。我有一个模糊的想法,它是指向内存中一连串字节数据的指针。但是我该如何更新呢?这在代码中实际上是什么样的?
编辑
这是一个可以使用的基本代码示例。我怎样才能让它做一些像在屏幕上创建一个红色方块这样简单的事情?
let tex = SKMutableTexture(size: CGSize(width: 10, height: 10))
tex.modifyPixelDataWithBlock { (ptr:UnsafeMutablePointer<Void>, n:UInt) -> Void in
/* ??? */
}
UnsafeMutablePointer<Void>
是 Swift 等价于 void*
- 指向任何东西的指针。您可以访问底层内存作为其 memory
属性。通常,如果您知道底层类型是什么,您将首先强制指向该类型的指针。然后,您可以使用下标到达内存中的特定 "slot"。
例如,如果数据确实是一个 UInt8 值序列,您可以说:
let buffer = UnsafeMutablePointer<UInt8>(ptr)
您现在可以通过 buffer[0]
、buffer[1]
等访问单独的 UIInt8 值。
来自 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.
因此,当您获得 void*
时,基础数据采用 4x8 位流的形式。
您可以像这样操作这样的结构:
// 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
}
}