withUnsafeBytes ve C Birlikte Çalışabilirliği
Ham bayt bekleyen C API'lerine köprü kurun.
withUnsafeBytes ve C Birlikte Çalışabilirliği, CoddyKit'te ücretsiz bir Swift Academy dersidir. Bu, 4 dersinin 4. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, Swift Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. Swift Academy kursu toplamda 4 dersten oluşur.
Türü Belirlenmiş Veriden Ham Baytlara
Bazen bir değeri Int veya struct olarak değil, onu özetlemek, bir dosyaya yazmak ya da bir C API'sine vermek için ham baytlar dizisi olarak görmeniz gerekir. withUnsafeBytes tam olarak bunu sağlar: bir değerin depolama alanının UInt8 olarak geçici görünümünü.
var value: UInt32 = 0x01020304
withUnsafeBytes(of: &value) { rawBuffer in
print(rawBuffer.count) // 4 bytes
}UnsafeRawBufferPointer
Kapanış, eleman türü olmayan bir bayt arabelleği olan UnsafeRawBufferPointer alır. Tek tek UInt8 değerlerini okumak için bu arabelleği dizinlersiniz. Salt okunurdur; değiştirilebilir biçimi withUnsafeMutableBytes şeklindedir.
var value: UInt32 = 0x01020304
withUnsafeBytes(of: &value) { bytes in
for b in bytes { print(String(format: "%02x", b)) }
}
// Order depends on endiannessBayt Sıralaması Önemlidir
Gözlemlediğiniz bayt sırası platformun bayt sıralamasına bağlıdır. Küçük endian makinelerde (Apple silicon, Intel) en düşük anlamlı bayt önce gelir. Bir protokol için serileştirme yaparken bigEndian veya littleEndian ile açıkça dönüştürün.
let host: UInt32 = 0x01020304
let networkOrder = host.bigEndian
var be = networkOrder
withUnsafeBytes(of: &be) { bytes in
// Always 01 02 03 04 regardless of platform
print(Array(bytes))
}Bir Yapının Baytları
withUnsafeBytes(of:), yapılar da dâhil olmak üzere her değerle çalışır. Arabellek uzunluğu MemoryLayout<T>.size değerine eşittir; dolgu baytları dâhil edilir, ancak içerikleri belirtilmemiştir.
struct RGB { var r: UInt8; var g: UInt8; var b: UInt8 }
var color = RGB(r: 255, g: 128, b: 0)
withUnsafeBytes(of: &color) { bytes in
print(bytes[0], bytes[1], bytes[2]) // 255 128 0
}Baytlardan Değer Yükleme
Ham baytları türü belirlenmiş bir değer olarak yeniden yorumlamak için ham arabellek üzerinde load(fromByteOffset:as:) kullanın. Ofset, türün hizalama gereksinimine uymalı ve baytlar gerçekten o türün geçerli bir değerini temsil etmelidir.
let raw: [UInt8] = [0x04, 0x03, 0x02, 0x01]
let n = raw.withUnsafeBytes { ptr in
ptr.load(fromByteOffset: 0, as: UInt32.self)
}
print(String(format: "0x%08x", n))Paketlenmiş Veriler için loadUnaligned
İkili biçimler çoğu zaman alanları hizalama dolgusu olmadan paketler. Hizalanmamış bir ofsette load çağırmak tanımsız davranıştır; herhangi bir ofsetten güvenle okumak için bunun yerine loadUnaligned(fromByteOffset:as:) kullanın.
let packet: [UInt8] = [0xFF, 0x04, 0x03, 0x02, 0x01]
let field = packet.withUnsafeBytes { ptr in
ptr.loadUnaligned(fromByteOffset: 1, as: UInt32.self)
}
print(field)Swift Verilerini C'ye Aktarma
Birçok C işlevi uzunlukla birlikte const void * kabul eder. Data ve diziler, kopyalama yapmadan baseAddress ile count değerlerini doğrudan geçirmenizi sağlayan withUnsafeBytes özelliğini sunar.
import Foundation
let data = Data([0x68, 0x69]) // "hi"
data.withUnsafeBytes { (raw: UnsafeRawBufferPointer) in
if let base = raw.baseAddress {
// c_consume(base, raw.count)
print("ptr", base, "len", raw.count)
}
}C İşaretçisi Alma
Bir C geri çağırması size const void * ve bir uzunluk verdiğinde, güvenle üzerinde dolaşmak için bunu bir UnsafeRawBufferPointer içine sarın. Swift, C işaretçisini UnsafeRawPointer? olarak içe aktarır.
func handleC(_ ptr: UnsafeRawPointer, _ len: Int) {
let buffer = UnsafeRawBufferPointer(start: ptr, count: len)
let checksum = buffer.reduce(0) { $0 &+ Int($1) }
print("checksum:", checksum)
}bindMemory ve Yeniden Yorumlama
Ham bir bölgeyi türü belirlenmiş elemanlar olarak ele almak için bindMemory(to:capacity:) derleyiciye bölgenin nasıl yorumlanacağını söyler. Bunun yanlış kullanılması (aynı belleği birbiriyle uyumsuz iki türe bağlamak), Swift'in katı diğer adlandırma kurallarını ihlal eder ve tanımsız davranışa yol açar.
let raw = UnsafeMutableRawPointer.allocate(
byteCount: 8, alignment: 8)
defer { raw.deallocate() }
let typed = raw.bindMemory(to: Int.self, capacity: 1)
typed.pointee = 1234
print(typed.pointee)assumingMemoryBound ve bindMemory Karşılaştırması
bindMemory, belleğin yorumlanma biçimini kalıcı olarak değiştirir; assumingMemoryBound(to:) ise hiçbir şeyi değiştirmeden belleğin zaten bu türe bağlandığını varsayar. İkinci yöntemi yalnızca mevcut bağlamadan emin olduğunuzda, örneğin belleğin verilen türü tuttuğunu bildiğiniz durumlarda kullanın.
func sumInts(_ raw: UnsafeRawPointer, _ count: Int) -> Int {
let p = raw.assumingMemoryBound(to: Int.self)
var total = 0
for i in 0..<count { total += p[i] }
return total
}Güvenlik Kontrol Listesi
Ham baytlar ve C birlikte çalışabilirliği, çökmelerin çoğunun gizlendiği yerdir. Şunları unutmayın:
- Kapanışın işaretçisinin dışarı kaçmasına asla izin vermeyin.
- Hizalamaya uyun veya
Unalignedvaryantlarını kullanın. - Serileştirme sırasında
endiannessdeğerini açıkça ele alın. - Belleği birbiriyle çakışan türlere yeniden bağlamayın.
- Boş arabellekler için
nilbaseAddressdurumuna karşı önlem alın.
// Convert any value to a hex string safely
import Foundation
func hex<T>(_ v: T) -> String {
var value = v
return withUnsafeBytes(of: &value) { bytes in
bytes.map { String(format: "%02x", $0) }.joined()
}
}Kısa Kontrol
Paketlenmiş ikili verileri okuma konusundaki kavrayışınızı sınayın.
Özet
Swift değerleri ile C arasında ham baytlar üzerinden bağlantı kurmayı öğrendiniz:
withUnsafeBytes(of:), her değeriUInt8olarak görüntüler.load/loadUnaligned, hizalamaya uyarak baytları türü belirlenmiş değerler olarak yeniden yorumlar.Datave diziler, işaretçi ile uzunluğu C'ye geçirmek içinwithUnsafeBytesözelliğini sunar.bindMemoryveassumingMemoryBound, ham belleğin nasıl türlendirileceğini denetler.- Bayt sıralaması, hizalama ve işaretçinin dışarı kaçması başlıca tehlikelerdir.
Yapay zeka eğitmeniyle Swift öğren — ücretsiz
Tarayıcında gerçek kod yaz ve çalıştır, 7/24 yapay zeka eğitmeninden anında yardım al; web'de ya da uygulamada kaldığın yerden devam et.
- Kurslar
- 122
- Dersler
- 409
Sıkça Sorulan Sorular
“withUnsafeBytes ve C Birlikte Çalışabilirliği” dersi ücretsiz mi?
Evet — “withUnsafeBytes ve C Birlikte Çalışabilirliği” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve Swift Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. Swift Academy kursu toplamda 4 dersten oluşur.
“withUnsafeBytes ve C Birlikte Çalışabilirliği” dersinde ne öğreneceğim?
Ham bayt bekleyen C API'lerine köprü kurun. Swift Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
Swift Academy öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te Swift Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 4. dersidir.
“withUnsafeBytes ve C Birlikte Çalışabilirliği” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu Swift Academy dersinde kod yazıp çalıştırabilir miyim?
Evet. Her Swift Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- MemoryLayout ve Hizalama
- UnsafePointer ve UnsafeMutablePointer
- Güvenli Olmayan Tampon İşaretçileri
- withUnsafeBytes ve C Birlikte Çalışabilirliği