如何在Swift中使用UnsafeMutablePointer <OpaquePointer>?

l-马克l

UnsafeMutablePointer<OpaquePointer>Swift如何与某些Core Foundation框架一起使用?为什么要UnsafeMutablePointer<OpaquePointer>

给定,一般:一些UnsafeMutablePointer<SomeType>地方typealias SomeType = OpaquePointer

具体示例API

// SOURCE: import ApplicationServices.PrintCore
typealias PMPrinter = OpaquePointer
func PMSessionGetCurrentPrinter(_ printSession: PMPrintSession, _ currentPrinter: UnsafeMutablePointer<PMPrinter>)
func PMPrinterGetPaperList(PMPrinter, UnsafeMutablePointer<Unmanaged<CFArray>?>)

特定示例用例:获取打印机支持的纸张列表

let printInfo = NSPrintInfo.shared()
let printSession = PMPrintSession(printInfo.pmPrintSession())
var currentPrinterOptional: PMPrinter? = nil
PMSessionGetCurrentPrinter(printSession, &currentPrinterOptional!)
guard let currentPrinter = currentPrinterOptional else { return }

// Get the array of pre-defined PMPapers this printer supports.
// PMPrinterGetPaperList(PMPrinter, UnsafeMutablePointer<Unmanaged<CFArray>?>)
var paperListUnmanaged: Unmanaged<CFArray>?
PMPrinterGetPaperList(currentPrinter, &paperListUnmanaged)
guard let paperList = paperListUnmanaged?.takeUnretainedValue() as [AnyObject]? else { return }

观察到的错误

编译不运行。看起来(可能)合理的语法无法编译。

上面的示例获得以下(预期)运行时“致命错误:在展开Optional值时意外发现nil”

一些选择其他尝试:

// Compile Error: Address of variable 'currentPrinter' taken before is is initialized
var currentPrinter: PMPrinter
PMSessionGetCurrentPrinter(printSession, &currentPrinter)

// Compile Error: Nil cannot initialze specified type 'PMPrinter' (aka 'OpaquePointer')
var currentPrinter: PMPrinter = nil
PMSessionGetCurrentPrinter(printSession, &currentPrinter)

// Compile Error: Variable 'currentPrinterPtr' used before being initialized
var currentPrinterPtr: UnsafeMutablePointer<PMPrinter>
PMSessionGetCurrentPrinter(printSession, currentPrinterPtr)

// Compile OK: actually compiles
// Runtime Error: unexpectedly found nil while unwrapping an Optional value
var currentPrinterOptional: PMPrinter? = nil
PMSessionGetCurrentPrinter(printSession, &currentPrinterOptional!)

资源资源

苹果:核心印刷⇗
苹果:将Swift与Cocoa和Objective-C结合使用⇗

尽管文档提供了有用的信息,但难以理解的UnsafeMutablePointer<PMPrinter>使用typealias的可行实现UnsafeMutablePointer<OpaquePointer>

马丁·R

PMPrinter并且PMPaper在PrintCore框架中定义为指向“不完整类型”的指针

typedef struct OpaquePMPrinter*         PMPrinter;
typedef struct OpaquePMPaper*           PMPaper;

这些作为导入到Swift中OpaquePointer,使用起来有些麻烦。

的第二个参数PMSessionGetCurrentPrinter()是指向非可选 PMPrinter变量的指针,在Swift中,必须在将其作为inout参数传递之前对其进行初始化。初始化空指针的一种可能方法是使用unsafeBitCast

PMPaper从数组中获取对象的最简单方法似乎是使用CFArrayGetValueAtIndex()而不是将其桥接到Swift数组。会传回UnsafeRawPointer,可以转换成OpaquePointer

这在我的测试中有效:

let printInfo = NSPrintInfo.shared()
let printSession = PMPrintSession(printInfo.pmPrintSession())

var currentPrinter = unsafeBitCast(0, to: PMPrinter.self)
PMSessionGetCurrentPrinter(printSession, &currentPrinter);

var paperListUnmanaged: Unmanaged<CFArray>?
PMPrinterGetPaperList(currentPrinter, &paperListUnmanaged)
guard let paperList = paperListUnmanaged?.takeUnretainedValue() else {
    fatalError()
}
for idx in 0..<CFArrayGetCount(paperList) {
    let paper = PMPaper(CFArrayGetValueAtIndex(paperList, idx))!
    var width = 0.0, height = 0.0
    PMPaperGetWidth(paper, &width)
    PMPaperGetHeight(paper, &height)
    print(width, height)
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章