如何从CMutablePointer <cgfloat>转到Swift中的CGFloat [] </cgfloat>

时间:2014-06-05 03:58:40

标签: swift

我正在尝试将使用Facebook's pop library的ObjC类转换为Swift。 Pop使用相当多的C。

在ObjC中,我有一个看起来像这样的块......

prop.readBlock = ^(SHVGraphViewObjc *graphView, CGFloat values[]) {
                values[0] = [graphView.centerOffsets[idx] doubleValue];
            };

Swift中的等效闭包定义是

prop.readBlock = {(graphView: AnyObject!, values: CMutablePointer<CGFloat>) in }

我无法弄清楚如何将values[0] = [graphView.centerOffsets[idx] doubleValue];转换为Swift?如何让Swift知道CMutablePointer<CGFloat>应该是CGFloat[]

2 个答案:

答案 0 :(得分:9)

编辑:只是想从online documentation (PDF)学到更多东西后澄清一些事情。

Swift中有一些常用的指针类型,下面是它们如何映射到C等价物:

作为参数的指针

CConstVoidPointer     => const void *
CMutableVoidPointer   => void *
CConstPointer<Type>   => const Type * 
CMutablePointer<Type> => Type *

指针作为返回类型,变量和参数*

COpaquePointer      => void *
UnsafePointer<Type> => Type *

注意:当参数超过一个指针级别时,参数遵循此规则 ,否则请参见上文。

班级类型的指针

CConstPointer<Type>              => Type * const *
CMutablePointer<Type>            => Type * __strong *
AutoreleasingUnsafePointer<Type> => Type **

Swift Pointers

在Swift中使用CConstPointer<Type>指针时,您可以传递其中任何一个:

  • nil,将被评估为NULL指针
  • CConstPointer<Type>
  • CConstVoidPointer
  • CMutablePointer<Type>
  • A CMutableVoidPointer
  • AutoreleasingUnsafePointer<Type>值,必要时将转换为CConstPointer<Type>
  • 地址(Type运营商)传递的&
  • Type[]数组

注意: CConstVoidPointer也可以使用上述任何值。

在Swift中使用CMutablePointer<Type>指针时,您可以传递其中任何一个:

  • nil,将被评估为NULL指针
  • CMutablePointer<Type>
  • 地址(Type运营商)传递的&
  • 通过地址(Type[]运营商)传递的&数组

注意: CMutableVoidPointer除了CMUtableVoidPointer值外,还可以采用上述任何一项。

因此,在您的情况下,CMutablePointer<CGFloat>也可能是指向CGFloat值数组的指针。虽然我不完全确定如何在Swift中取消引用。 (也许是as运算符?)

答案 1 :(得分:3)

虽然SiLo的回答非常详细,但罗斯在其下面的评论回答了这里的具体问题,所以我想我会将这些问题扩展为完整答案。

我最近需要这样做才能通过Swift与我的GPUImage框架连接。对于我的Harris角点检测器,我在每个处理过的帧上使用一个回调块,它提供X,Y坐标对中的OpenGL浮点值的C数组,以及成对的数组。我使用C数组来提高性能,因为在实时视频中每秒会提供30到60次。在Objective-C中,我会使用以下代码进行设置:

UIImage *sourceImage = [UIImage imageNamed:@"ChairTest.png"];

GPUImageHarrisCornerDetector *cornerDetector = [[GPUImageHarrisCornerDetectionFilter alloc] init];

[cornerDetector setCornersDetectedBlock:^(GLfloat* cornerArray, NSUInteger cornersDetected, CMTime frameTime) {
    NSLog(@"Number of corners detected: %d", cornersDetected);
    NSLog(@"Corner 1, X: %f, Y: %f", cornerArray[0], cornerArray[1]);
}];

GPUImagePicture *inputPicture = [[GPUImagePicture alloc] initWithImage:sourceImage];
[inputPicture addTarget:cornerDetector];
[inputPicture processImage];

在我破译了正确的闭包语法后,我无法弄清楚如何访问输入C数组的值,我将角坐标移交给处理块。 Sean Heber's tweet about this指出了一种方法,我用它将上面的Objective-C翻译成以下的Swift代码:

let sourceImage = UIImage(named: "ChairTest.png")

let cornerDetector = GPUImageHarrisCornerDetectionFilter()

cornerDetector.cornersDetectedBlock = { (cornerArray:CMutablePointer<GLfloat>, cornersDetected:Int, frameTime:CMTime) in
    println("Number of corners detected: \(cornersDetected)")
    let corners = UnsafePointer<GLfloat>(cornerArray)
    println("Corner 1, X: \(corners[0]) Y: \(corners[1])")
}

let inputPicture = GPUImagePicture(image: sourceImage)
inputPicture.addTarget(cornerDetector)
inputPicture.processImage()

这似乎在功能上是相同的。使用.withUnsafePointer()可能更安全,但我还没有完全掌握语法。