Swift Academy · Ders

withUnsafeBytes ve C Birlikte Çalışabilirliği

Ham bayt bekleyen C API'lerine köprü kurun.

4. ders / 413 adım

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 endianness

Bayt 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 Unaligned varyantlarını kullanın.
  • Serileştirme sırasında endianness değerini açıkça ele alın.
  • Belleği birbiriyle çakışan türlere yeniden bağlamayın.
  • Boş arabellekler için nil baseAddress durumuna 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ğeri UInt8 olarak görüntüler.
  • load / loadUnaligned, hizalamaya uyarak baytları türü belirlenmiş değerler olarak yeniden yorumlar.
  • Data ve diziler, işaretçi ile uzunluğu C'ye geçirmek için withUnsafeBytes özelliğini sunar.
  • bindMemory ve assumingMemoryBound, 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.
Başlamak ücretsiz

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

  1. MemoryLayout ve Hizalama
  2. UnsafePointer ve UnsafeMutablePointer
  3. Güvenli Olmayan Tampon İşaretçileri
  4. withUnsafeBytes ve C Birlikte Çalışabilirliği
← Swift Academy Sayfasına Dön