Swift3 Swift 3:如何提供C型&x27;void*';对象到iOS框架以用于回调?

Swift3 Swift 3:如何提供C型&x27;void*';对象到iOS框架以用于回调?,swift3,Swift3,基金会挤满了函数,这些函数将一个不透明的void*info,然后再将它卖回来。在ARC之前的Objective C时代,您可以保留一个对象,提供它,然后在将它交还给回调函数时释放它 比如说, CGDataProviderRef CGDataProviderCreateWithData(void *info, const void *data, size_t size, CGDataProviderReleaseDataCallback releaseData); typedef void (*

基金会挤满了函数,这些函数将一个不透明的
void*info
,然后再将它卖回来。在ARC之前的Objective C时代,您可以保留一个对象,提供它,然后在将它交还给回调函数时释放它

比如说,

CGDataProviderRef CGDataProviderCreateWithData(void *info, const void *data, size_t size, CGDataProviderReleaseDataCallback releaseData);

typedef void (*CGDataProviderReleaseDataCallback)(void *info, const void *data, size_t size);
在这种情况下,您可以在
info
中提供一个保留对象,然后在回调中释放它(在适当的强制转换之后)


在Swift中我将如何做到这一点?

在苹果爱斯基摩人奎因的帮助下,我发现了如何做到这一点。给定一个对象:

let pixelBuffer: CVPixelBuffer
获取指针:

  • 在保留非托管对象后获取该对象:

    let fooU:Unmanaged=Unmanaged.passRetained(像素缓冲区)

  • 将其转换为原始指针

    让foo:unsafemeutablerawpointer=fooU.toOpaque()

  • 释放对象时恢复该对象:

  • 将原始指针转换为非托管类型化对象

    let-ptr:Unmanaged=Unmanaged.fromovaque(pixelPtr)

  • 释放时恢复实际对象

    let pixelBuffer:CVPixelBuffer=ptr.takeRetainedValue()

  • 以下代码已在应用程序中测试。注意:如果没有苹果的帮助,我永远不会明白这一点,因此问答!希望它能帮助别人

    另外,请注意
    @convention(c)
    ,这是我以前从未见过的

    let fooU: Unmanaged = Unmanaged.passRetained(pixelBuffer)
    let foo: UnsafeMutableRawPointer = fooU.toOpaque()
    /* Either "bar" works */
    /* let bar: @convention(c) (UnsafeMutableRawPointer?, UnsafeRawPointer, Int) -> Swift.Void = { */
    let bar: CGDataProviderReleaseDataCallback = {
        (_ pixelPtr: UnsafeMutableRawPointer?, _ data: UnsafeRawPointer, _ size: Int) in
    
        if let pixelPtr = pixelPtr {
            let ptr: Unmanaged<CVPixelBuffer> = Unmanaged.fromOpaque(pixelPtr)
            let pixelBuffer: CVPixelBuffer = ptr.takeRetainedValue()
            CVPixelBufferUnlockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))
            DispatchQueue.main.async {
                print("UNLOCKED IT!")
            }
        }
    }
    
    let val: CVReturn = CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))
    if  val == kCVReturnSuccess,
        let sourceBaseAddr = CVPixelBufferGetBaseAddress(pixelBuffer),
        let provider = CGDataProvider(dataInfo: foo, data: sourceBaseAddr, size: sourceRowBytes * height, releaseData: bar)
    {
        let colorspace = CGColorSpaceCreateDeviceRGB()
        let image = CGImage(width: width, height: height, bitsPerComponent: 8, bitsPerPixel: 32, bytesPerRow: sourceRowBytes,
                        space: colorspace, bitmapInfo: bitmapInfo, provider: provider, decode: nil,
                        shouldInterpolate: true, intent: CGColorRenderingIntent.defaultIntent)
        /* CVPixelBufferUnlockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0)) */
        return image
    } else {
        return nil
    }
    
    let fooU:Unmanaged=Unmanaged.passRetained(像素缓冲区)
    让foo:unsafemeutablerawpointer=fooU.toOpaque()
    /*两个“酒吧”都可以*/
    /*let bar:@convention(c)(UnsafeMutableRawPointer?,UnsafeRawPointer,Int)->Swift.Void={*/
    let bar:CGDataProviderReleaseDataCallback={
    (\uPixelptr:UnsafeMutableRawPointer?,\uData:UnsafeRawPointer,\uSize:Int)中
    如果让pixelPtr=pixelPtr{
    let ptr:Unmanaged=Unmanaged.from不透明(像素ptr)
    let pixelBuffer:CVPixelBuffer=ptr.takeRetainedValue()
    CVPixelBufferUnlockBaseAddress(pixelBuffer,CVPixelBufferLockFlags(rawValue:0))
    DispatchQueue.main.async{
    打印(“解锁它!”)
    }
    }
    }
    let val:CVReturn=CVPixelBufferLockBaseAddress(pixelBuffer,CVPixelBufferLockFlags(rawValue:0))
    如果val==kCVReturnSuccess,
    让sourceBaseAddr=CVPixelBufferGetBaseAddress(pixelBuffer),
    let provider=CGDataProvider(dataInfo:foo,data:sourceBaseAddr,size:sourceRowBytes*height,releaseData:bar)
    {
    让colorspace=CGColorSpaceCreateDeviceRGB()
    让image=CGImage(宽度:宽度,高度:高度,bitsPerComponent:8,bitsPerPixel:32,bytesPerRow:sourceRowBytes,
    空格:颜色空间,bitmapInfo:bitmapInfo,提供程序:提供程序,解码:无,
    shouldInterpolate:true,intent:CGColorRenderingIntent.defaultIntent)
    /*CVPixelBufferUnlockBaseAddress(pixelBuffer,CVPixelBufferLockFlags(rawValue:0))*/
    返回图像
    }否则{
    归零
    }
    

    Quinn最近更新了苹果论坛的帖子,说不知怎么的,这项技术从来没有出现在两个苹果Swift文档中,他只是输入了一个rdar来添加它。所以你在其他任何地方都找不到这一信息(好吧,至少现在!)

    @vadian是的,这是同样的技巧。问题是标题-你想改变“自我”以外的东西吗?但无论如何,我会删除我的答案。