【问题标题】:Convert CFContextRef to mutable void pointer in swift?快速将 CFContextRef 转换为可变 void 指针?
【发布时间】:2014-06-18 12:39:46
【问题描述】:

我正在尝试将此 objc 代码转换为 swift:

CGContextRef contextRef = CGBitmapContextCreate(NULL,
                                                proposedRect.size.width,
                                                proposedRect.size.height,
                                                CGImageGetBitsPerComponent(imageRef),
                                                0,
                                                colorSpaceRef,
                                                (CGBitmapInfo)kCGImageAlphaPremultipliedFirst);
NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:contextRef flipped:NO];

到目前为止,我最终得到了这个:

var bitmapContext: CGContext = CGBitmapContextCreate(data, UInt(proposedRect.width), UInt(proposedRect.height), CGImageGetBitsPerComponent(image), 0, colorSpace, CGBitmapInfo(CGImageAlphaInfo.PremultipliedFirst.toRaw()))
let context = NSGraphicsContext(graphicsPort: bitmapContext, flipped: false)

问题在于CGBitmapContextCreate 返回CGContext 类型,而NSGraphicsContext 初始化程序接受graphicsPort 作为CMutableVoidPointer 类型。那么如何将CGContext 转换为CMutableVoidPointer

在此处找到相关的反向类型转换,但对我没有太大帮助 How to convert COpaquePointer in swift to some type (CGContext? in particular)

【问题讨论】:

  • 传递&contextRef 有效吗?
  • 它没有。 &contextRefCGContextRef * 类型,这不是我需要的。基本上我需要简单的演员 CGContextRef as void *

标签: pointers types casting swift void


【解决方案1】:

我最终得到了reinterpretCast 函数返回bitmapContext 地址的中间Int 变量。

var bitmapContext: CGContext = CGBitmapContextCreate(...)

let bitmapContextAddress: Int = reinterpretCast(bitmapContext)
let bitmapContextPointer: CMutableVoidPointer = COpaquePointer(UnsafePointer<CGContext>(bitmapContextAddress))
let context = NSGraphicsContext(graphicsPort: bitmapContextPointer, flipped: false)

【讨论】:

  • 感谢您的回答!不过,我认为reinterpretCast 已经从语言中消失了;您需要改用unsafeBitCast
  • 当然,你是对的,但是 NSGraphicsContext 的对象初始化器已经改变了它的签名,所以不再需要位转换
【解决方案2】:

这里的文档:https://developer.apple.com/library/prerelease/ios/documentation/swift/conceptual/buildingcocoaapps/InteractingWithCAPIs.html

声明如下:

当函数被声明为采用 CMutableVoidPointer 参数时, 它可以接受与任何类型的 CMutablePointer 相同的操作数 输入。

从那以后,它应该像这样工作:

var p: CMutablePointer<CGContext> = &bitmapContext
NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:p flipped:NO];

实际上,您应该能够将&amp;bitmapContext 直接传递给CMutableVoidPointer 参数。

Swift 没有 C 意义上的“指针”。

【讨论】:

  • 原始类型CGContextRef 已经是一个指针。所以在 objc 中,我可以进行简单的演员 void *pointer = CGBitmapContextCreate(...) 并得到我需要的东西。在 swift &amp;bitmapContext 是指向指针 void ** 的指针,它不完全是 NSGraphicsContext 接受的 graphicsPort 参数
  • @chebur 这是 Swift,不是 C,不是 C++,不是 ObjC。 Swift 中没有指针的概念。如果你不接受或不理解这一点,你根本就不会得到 Swift。
  • 您试图建议的是通过执行&amp;bitmapContext 来获得指向CGContextRef 的指针。但是Typically graphicsPort is a CGContextRef (opaque type) object。这意味着该函数完全期望 CGContextRef 值被简单地向下转换为 CMutableVoidPointer(在 C 中为 void *),而不是您之前建议的指向 CGContextRef 的指针。
  • 再一次,你是在用 C 语言来思考。在 Swift 中,&amp; 不是引用运算符,并且从 ObjC 到 Swift 的桥接处理在内部传递不透明类型。即&amp;bitmapContext 确实创建指向CGContextRef 的指针。 Swift 中没有指针之类的东西。
  • Swift 提供various types for pointers to enable direct memory access。里面有例子来展示&amp;的正确用法。到目前为止&amp; 的意思是获取一个值的引用
猜你喜欢
  • 2016-01-12
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 2021-07-22
  • 2012-11-21
  • 1970-01-01
  • 2021-09-20
相关资源
最近更新 更多