Swift'de Standart C Kitaplığı işlevleriyle oynatırken, C dizelerini geçirirken sorunlarına rastladım. Basit bir örnek (sadece sorunu göstermek için)Swift'de C dizeleriyle çalışma, veya: Nasıl Yapılır: UnsafePointer <CChar> - CString'e dönüştürme
char * strdup(const char *s1);
strdup()
dönüş değeri, başka bir strdup()
geçirilebilir anlamına gelir
func strdup(_: CString) -> UnsafePointer<CChar>
olarak Swift maruz, Temel kütüphane işlevi olarak çağrı:
let s1 : CString = "abc"
let s2 = strdup(s1) // OK, s2 is a UnsafePointer<CChar>
let s3 = strdup(s2) // error: could not find an overload for '__conversion' that accepts the supplied arguments
sorum şu: nasıl oluşturulur bir SwiftBir UnsafePointer<CChar>
, 'dan 10, bir standart kütüphane fonksiyonu tarafından döndürülen C dizisi başka bir işleve iletilebilir mi? Bulabildiğim
tek yolu (How do you convert a String to a CString in the Swift Language? gelen kullanarak kod) 'dir:
let s2a = String.fromCString(s2).bridgeToObjectiveC().UTF8String
let s3 = strdup(s2a)
Ama iki nedenden dolayı bu tatmin edici bulmuyorum:
- Bu basit için çok karmaşık olduğunu görev.
- (Esas neden :) Yukarıdaki dönüşümler yalnızca C dizesi geçerli bir UTF-8 dizesiyle çalışır, aksi halde çalışma zamanı istisnasıyla başarısız olur. Ancak bir C dizesi, bir NUL karakteri ile sınırlandırılmış bir rasgele karakter dizisidir.
Açıklamalar/Arka plan: Tabii, Swift String
veya amaç-C NSString
gibi yüksek seviyeli veri yapılarını kullanarak yüksek seviyede fonksiyonlar tercih edilmektedir. Ancak, Foundation çerçevelerinde tam bir karşılığı olmayan Standart C Kitaplığı'nda BSD işlevleri vardır.
Bu soruna, Accessing temp directory in Swift numaralı telefonu yanıtlamaya çalışırken rastladım. Burada, mkdtemp()
, NSFileManager
değiştirmenin (bildiğim kadarıyla) olduğu bir BSD işlevidir. yer alır mkdtemp()
döner bir UnsafePointer<CChar>
bir CString
argüman alır NSFileManager
fonksiyonu stringWithFileSystemRepresentation
geçirilecek.
Güncelleme: Swift içine C-Strings haritalama basitleştirildi çünkü Xcode 6 beta 6 itibariyle bu sorun artık yok. Sadece
let s1 = "abc" // String
let s2 = strdup(s1) // UnsafeMutablePointer<Int8>
let s3 = strdup(s2) // UnsafeMutablePointer<Int8>
let s4 = String.fromCString(s3) // String
Anonim downvoter sayesinde bana soruları yanıtlamak için hatırlattı :) –