Swift Academy · Pelajaran

withUnsafeBytes dan Interoperabilitas C

Hubungkan ke API C yang mengharapkan byte mentah.

Pelajaran 4 dari 413 langkah

withUnsafeBytes dan Interoperabilitas C adalah pelajaran Swift Academy gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Swift Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Swift Academy mencakup 4 pelajaran total.

Dari Tipe ke Bita Mentah

Terkadang Anda perlu melihat suatu nilai bukan sebagai Int atau struct, melainkan sebagai rangkaian bita mentah—untuk melakukan hash, menulisnya ke berkas, atau menyerahkannya ke API C. withUnsafeBytes memberi Anda tepat hal tersebut: tampilan sementara penyimpanan suatu nilai sebagai UInt8.

var value: UInt32 = 0x01020304
withUnsafeBytes(of: &value) { rawBuffer in
    print(rawBuffer.count) // 4 bytes
}

UnsafeRawBufferPointer

Fungsi penutupan menerima UnsafeRawBufferPointer—buffer bita tanpa tipe elemen. Anda mengaksesnya dengan indeks untuk membaca setiap nilai UInt8. Buffer ini hanya baca; bentuk yang dapat diubah adalah withUnsafeMutableBytes.

var value: UInt32 = 0x01020304
withUnsafeBytes(of: &value) { bytes in
    for b in bytes { print(String(format: "%02x", b)) }
}
// Order depends on endianness

Urutan Bita Itu Penting

Urutan bita yang Anda amati bergantung pada urutan bita platform. Pada mesin little-endian (Apple silicon, Intel), bita paling tidak signifikan muncul lebih dahulu. Saat melakukan serialisasi untuk suatu protokol, lakukan konversi secara eksplisit dengan bigEndian atau littleEndian.

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))
}

Bita dari Struktur

withUnsafeBytes(of:) dapat digunakan pada nilai apa pun, termasuk struktur. Panjang buffer sama dengan MemoryLayout<T>.size, dan bita pengisi apa pun ikut disertakan, tetapi isinya tidak ditentukan.

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
}

Memuat Nilai dari Bita

Untuk menafsirkan ulang bita mentah sebagai nilai bertipe, gunakan load(fromByteOffset:as:) pada buffer mentah. Offset harus mengikuti penyelarasan tipe tersebut, dan bita harus benar-benar merepresentasikan nilai yang valid untuk tipe itu.

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))

loadUnaligned untuk Data Terpadatkan

Format biner sering memadatkan bidang tanpa bita pengisi untuk penyelarasan. Memanggil load pada offset yang tidak selaras merupakan perilaku yang tidak terdefinisi; gunakan loadUnaligned(fromByteOffset:as:) untuk membaca dengan aman dari offset mana pun.

let packet: [UInt8] = [0xFF, 0x04, 0x03, 0x02, 0x01]
let field = packet.withUnsafeBytes { ptr in
    ptr.loadUnaligned(fromByteOffset: 1, as: UInt32.self)
}
print(field)

Menjembatani Data Swift ke C

Banyak fungsi C menerima const void * serta panjang. Data dan array menyediakan withUnsafeBytes, sehingga Anda dapat meneruskan baseAddress dan count secara langsung tanpa menyalin.

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)
    }
}

Menerima Penunjuk C

Saat panggilan balik C memberikan const void * dan panjang, bungkus penunjuk tersebut dalam UnsafeRawBufferPointer agar dapat melakukan iterasi dengan aman. Swift akan mengimpor penunjuk C tersebut sebagai UnsafeRawPointer?.

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 dan Penafsiran Ulang

Untuk memperlakukan wilayah mentah sebagai elemen bertipe, bindMemory(to:capacity:) memberi tahu compiler cara menafsirkannya. Penyalahgunaan ini, yaitu mengikat memori yang sama ke dua tipe yang tidak kompatibel, melanggar aturan alias ketat Swift dan menghasilkan perilaku yang tidak terdefinisi.

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 vs bindMemory

bindMemory mengubah cara memori ditafsirkan secara permanen; assumingMemoryBound(to:) menyatakan bahwa memori tersebut sudah terikat ke tipe itu tanpa mengubah apa pun. Gunakan yang terakhir hanya jika Anda yakin dengan pengikatan yang ada, misalnya pada memori yang Anda ketahui menyimpan tipe tersebut.

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
}

Daftar Periksa Keamanan

Interoperabilitas bita mentah dan C adalah tempat sebagian besar kerusakan tersembunyi. Ingatlah hal-hal berikut:

  • Jangan pernah membiarkan penunjuk fungsi penutupan keluar.
  • Patuhi penyelarasan atau gunakan varian Unaligned.
  • Tangani endianness secara eksplisit saat melakukan serialisasi.
  • Jangan mengikat ulang memori ke tipe yang saling bertentangan.
  • Lindungi diri dari nil pada baseAddress untuk buffer kosong.
// 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()
    }
}

Pemeriksaan Singkat

Uji pemahaman Anda tentang membaca data biner yang dipadatkan.

Ringkasan

Anda telah mempelajari cara menjembatani nilai Swift dan C melalui bita mentah:

  • withUnsafeBytes(of:) menampilkan nilai apa pun sebagai UInt8.
  • load / loadUnaligned menafsirkan ulang bita sebagai nilai bertipe dengan tetap mengikuti penyelarasan.
  • Data dan array menyediakan withUnsafeBytes untuk meneruskan penunjuk dan panjang ke C.
  • bindMemory dan assumingMemoryBound mengatur cara memori mentah diberi tipe.
  • Urutan bita, penyelarasan, dan keluarnya penunjuk dari fungsi penutupan merupakan bahaya utama.
Gratis untuk memulai

Belajar Swift dengan tutor AI — gratis

Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.

Kursus
122
Pelajaran
409

Pertanyaan yang Sering Diajukan

Apakah pelajaran “withUnsafeBytes dan Interoperabilitas C” gratis?

Ya — teks lengkap “withUnsafeBytes dan Interoperabilitas C” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Swift Academy, upgrade ke CoddyKit PRO. Kursus Swift Academy mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “withUnsafeBytes dan Interoperabilitas C”?

Hubungkan ke API C yang mengharapkan byte mentah. Kamu berlatih Swift Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Swift Academy?

Tidak diperlukan pengalaman sebelumnya. Swift Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “withUnsafeBytes dan Interoperabilitas C” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Swift Academy ini?

Ya. Setiap pelajaran Swift Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. MemoryLayout dan Alignment
  2. UnsafePointer dan UnsafeMutablePointer
  3. Pointer Buffer Tidak Aman
  4. withUnsafeBytes dan Interoperabilitas C
← Kembali ke Swift Academy