7

Ich versuche, etwas Code auf Linux zu kompilieren, der sowohl CoreFoundation als auch Foundation verwendet, aber Linux implementiert Bridging nicht in der gleichen Weise wie Mac OS und iOS.Bridging zu/von CoreFoundation unter Linux

Bridging zwischen Objective-C und Swift arbeitet:

import Foundation 
import CoreFoundation 
import Glibc 

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

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

Aber ich kann nicht herausfinden, wie man Corefoundation zu überbrücken. Ich kann einfach nicht eine NSString an eine Funktion, die eine CFString will:

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' 

ich es wie auf macOS werfen kann nicht einfach:

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? 

Mit as! wie die Fehlermeldung schlägt compiles aber Ergebnisse bei einem Crash zur Laufzeit (Illegal instruction) und as? erzeugt den Fehler:

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

Bridging.swift verfügt über Protokolle zum Konvertieren zwischen NS- und CF-Typen, und viele Typen haben Initialisierer und Eigenschaften, aber das sind alle internal oder private. I könnte verwenden Sie einfach , aber das muss mit anderen Klassenpaare wie InputStream und CFReadStream arbeiten.

Fehle ich etwas hier, oder gibt es wirklich keine Möglichkeit, zwischen Foundation und CoreFoundation-Typen unter Linux zu konvertieren?

+0

Funktioniert das? http://Stackoverflow.com/a/24900185/603977 Hässliche Doppel-Besetzung. Ich weiß nichts über Linux. Das große "Gotcha" mit Swift unter Linux ist, dass die ObjC-Laufzeit nicht vorhanden ist. –

+0

@JoshCaswell Nein; Bridging zwischen Swift und Foundation [wird vom Compiler noch nicht automatisch gemacht] (https://github.com/apple/swift-corelibs-foundation/blob/master/Docs/Issues.md), weshalb ich muss benutze die temporäre '_bridgeToObjectiveC' Methode, und ich habe in meinem dritten Beispiel versucht, von' NSString' nach 'CFString' zu konvertieren. – NobodyNada

Antwort

1

Es sieht aus wie ich kann unsafeBitCastNSString zu/von 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!" 

Das macht Sinn, da Corefoundation und Foundation-Typen entwickelt wurden das gleiche Speicherlayout haben - deshalb gebührenfreie Brückenarbeiten. Ich bin etwas überrascht, dass es aber mit der Swift-Implementierung von Foundation funktioniert.