繁体   English   中英

如何使用Swift的UnsafeMutablePointer <UnsafeMutablePointer <Void >>引用?

[英]How do I work with a UnsafeMutablePointer<UnsafeMutablePointer<Void>> reference from Swift?

我正在使用SceneKit的SCNParticleSystem构建测试应用程序。 它有一个回调,允许您修改每个帧上的粒子属性。 这个回调的签名是

typealias SCNParticleModifierBlock = (UnsafeMutablePointer<UnsafeMutablePointer<Void>>, UnsafeMutablePointer<Int>, Int, Int, Float) -> Void

来自apple开发人员站点的参考 - SCNParticleSystem_Class

我不知道如何从Swift访问和修改此引用。 如果这是C中,它会是一个** ,我可以像解引用数组。

经过一番预测后,我已经达到了这个目的:

..... 
           particleSystem?.addModifierForProperties([SCNParticlePropertySize], atStage: SCNParticleModifierStage.PostDynamics, withBlock: doit2)
}

struct Foos {
    var size:float_t
}
func doit2(data:UnsafeMutablePointer<UnsafeMutablePointer<Void>>, dataStride: UnsafeMutablePointer<Int>, start:Int, end:Int, deltaTime:Float) -> Void {
    let myptr = UnsafeMutablePointer<UnsafeMutablePointer<Foos>>(data)
    print("indexes",start,end)
    for i in 0 ..< end {
        print(i,myptr[i].memory.size)
    }
}¸

这适用于第一个粒子,但在第二个粒子上崩溃。 第一次调用该函数时,有0个粒子,因此它会跳过循环。 第二次有三个粒子,所以它试图将它们打印出来。 第一个尺寸值为0.9,接缝合理。 第二个大小值显然是假的,然后它崩溃了,我进入调试器。

indexes 0 0
indexes 0 3
0 0.929816
1 1.51296e-39
(lldb)

我可以告诉我,互联网上没有人使用这个功能。 我找到的唯一参考是Apple的文档,它只为它提供ObjC示例,而不是Swift。

帮我!

为了考试:

var data = [[0.1, 0.2],[0.3, 0.4],[0.5, 0.6]]
let pData = UnsafeMutablePointer<UnsafeMutablePointer<Void>>(data)
// how to reconstruct the original data ??

// we need to know how much data we have
let count = data.count
// we need to know what type of data we have
let p2 = UnsafeMutablePointer<Array<Double>>(pData)
// access the data
for i in 0..<count {
    print((p2 + i).memory)
}
// [0.1, 0.2]
// [0.3, 0.4]
// [0.5, 0.6]

我认为在你的代码中,myptr的声明是错误的

let myptr = UnsafeMutablePointer<UnsafeMutablePointer<Foos>>(data)

示例中的dataStride.count应为1(属性数),其元素的值应为float的大小(属性的大小)。

还要小心! 你的循环应该是这样的

for i in start..<end {
...
}

你确定开始是0 ???

使用非常相似的SCNParticleEventBlock,我在Swift3中编写了处理程序

 ps.handle(SCNParticleEvent.birth, forProperties [SCNParticleSystem.ParticleProperty.color]) {
    (data:UnsafeMutablePointer<UnsafeMutableRawPointer>, dataStride:UnsafeMutablePointer<Int>, indicies:UnsafeMutablePointer<UInt32>?, count:Int) in

    for i in 0..<count {

        // get an UnsafeMutableRawPointer to the i-th rgba element in the data
        let colorsPointer:UnsafeMutableRawPointer = data[0] + dataStride[0] * i

        //  convert the UnsafeMutableRawPointer to a typed pointer by binding it to a type:
        let floatPtr = colorsPointer.bindMemory(to: Float.self, capacity: dataStride[0])
        // convert that to a an  UnsafeMutableBufferPointer
        var rgbaBuffer = UnsafeMutableBufferPointer(start: floatPtr, count: dataStride[0])
        // At this point, I could convert the buffer to an Array, but doing so copies the data into the array and any changes made in the array are not reflected in the original data.  UnsafeMutableBufferPointer are subscriptable, nice.
        //var rgbaArray = Array(rgbaBuffer)

        // about half the time, mess with the red and green components
        if(arc4random_uniform(2) == 1) {
            rgbaBuffer[0] = rgbaBuffer[1]
            rgbaBuffer[1] = 0
        }
    }
 }

我的SO中的更多细节在这里提出并回答了问题

这里这里有几个要点

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM