简体   繁体   English

在 Linux 上连接到/从 CoreFoundation

[英]Bridging to/from CoreFoundation on Linux

I'm trying to compile some code on Linux that uses both CoreFoundation and Foundation, but Linux doesn't implement bridging in the same way macOS and iOS do.我正在尝试在 Linux 上编译一些同时使用 CoreFoundation 和 Foundation 的代码,但 Linux 并没有像 macOS 和 iOS 那样实现桥接。

Bridging between Objective-C and Swift works: Objective-C 和 Swift 之间的桥梁工作:

import Foundation
import CoreFoundation
import Glibc

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

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

But I can't figure out how to bridge to CoreFoundation.但我不知道如何连接到 CoreFoundation。 I can't just pass an NSString to a function that wants a CFString :我不能只是将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'

I can't just cast it like on macOS:我不能像在 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?

Using as! as! like the error message suggests compiles but results in a crash at runtime ( Illegal instruction ), and as?就像错误消息建议编译但在运行时导致崩溃( Illegal instruction ),以及as? produces the error:产生错误:

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

Bridging.swift has protocols for converting between NS and CF types, and many types have initializers and properties, but those are all internal or private . Bridging.swift有在 NS 和 CF 类型之间转换的协议,许多类型都有初始化器和属性,但这些都是internalprivate I could just use CFStringCreateWithCString , but this needs to work with other class pairs like InputStream and CFReadStream .可以只使用CFStringCreateWithCString ,但这需要与其他类对一起使用,如InputStreamCFReadStream

Am I missing something here, or is there really no way to convert between Foundation and CoreFoundation types on Linux?我在这里遗漏了什么,还是真的没有办法在 Linux 上的 Foundation 和 CoreFoundation 类型之间进行转换?

It looks like I can unsafeBitCast NSString to/from CFString :看起来我可以unsafeBitCast NSString到/从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!"

This makes sense, since CoreFoundation and Foundation types were designed to have the same memory layout -- that's why toll-free bridging works.这是有道理的,因为 CoreFoundation 和 Foundation 类型被设计为具有相同的内存布局——这就是免费桥接工作的原因。 I'm somewhat surprised that it works with the Swift implementation of Foundation though.我有点惊讶它可以与 Foundation 的 Swift 实现一起使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM