Соединение с / с CoreFoundation в 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, и многие типы имеют инициализаторы и свойства, но все они internal
или же private
, Я мог бы просто использовать CFStringCreateWithCString
, но это должно работать с другими парами классов, такими как InputStream
а также CFReadStream
,
Я что-то здесь упускаю или действительно нет способа конвертировать между типами Foundation и CoreFoundation в Linux?
1 ответ
Похоже я могу 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!"
Это имеет смысл, поскольку типы CoreFoundation и Foundation были спроектированы таким образом, чтобы иметь одинаковую структуру памяти, поэтому работает бесплатный мост. Я несколько удивлен тем, что это работает с реализацией Swift Foundation.