在 Linux 上桥接 to/from CoreFoundation

Bridging to/from CoreFoundation on Linux

我正在尝试在 Linux 上编译一些同时使用 CoreFoundation 和 Foundation 的代码,但是 Linux 没有像 macOS 和 iOS 那样实现桥接。

Objective-C 和 Swift 之间的桥接有效:

import Foundation
import CoreFoundation
import Glibc

func wantsNSString(_ string: NSString) {
        print(string)
}

let string = "Hello, world!"
wantsNSString(string._bridgeToObjectiveC())

但我不知道如何连接到 CoreFoundation。我不能只将 NSString 传递给需要 CFString:

的函数
import Foundation
import CoreFoundation
import Glibc

func wantsCFString(_ string: CFString) {
        print(string)
}

let string = "Hello, world!"
wantsCFString(string._bridgeToObjectiveC()) //error: cannot convert value of type 'String._ObjectType' (aka 'NSString') to expected argument type 'CFString'

我不能像在 macOS 上那样投射它:

import Foundation
import CoreFoundation
import Glibc

func wantsCFString(_ string: CFString) {
        print(string)
}

let string = "Hello, world!"
wantsCFString(string._bridgeToObjectiveC() as CFString)
//error: 'String._ObjectType' (aka 'NSString') is not convertible to 'CFString'; did you mean to use 'as!' to force downcast?

像错误消息一样使用 as! 提示编译但导致运行时崩溃 (Illegal instruction),并且 as? 产生错误:

error: conditional downcast to CoreFoundation type 'CFString' will always succeed

Bridging.swift有NS和CF类型之间转换的协议,很多类型都有初始化器和属性,但那些都是internalprivate。我 可以 只使用 CFStringCreateWithCString,但这需要与其他 class 对一起使用,例如 InputStreamCFReadStream.

我是不是遗漏了什么,或者真的没有办法在 Linux 上的 Foundation 和 CoreFoundation 类型之间进行转换?

看来我可以unsafeBitCast NSString to/from CFString:

import Foundation
import CoreFoundation
import Glibc

func wantsCFString(_ string: CFString) {
        print(string)
}

let string = "Hello, world!"
wantsCFString(unsafeBitCast(string._bridgeToObjectiveC(), to: CFString.self)
//prints "Hello, world!"

这是有道理的,因为 CoreFoundation 和 Foundation 类型被设计为具有相同的内存布局——这就是免费桥接工作的原因。我有点惊讶它与 Foundation 的 Swift 实现一起工作。