withUnsafeBytes dan Interoperabilitas C
Hubungkan ke API C yang mengharapkan byte mentah.
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 endiannessUrutan 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
endiannesssecara eksplisit saat melakukan serialisasi. - Jangan mengikat ulang memori ke tipe yang saling bertentangan.
- Lindungi diri dari
nilpadabaseAddressuntuk 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 sebagaiUInt8.load/loadUnalignedmenafsirkan ulang bita sebagai nilai bertipe dengan tetap mengikuti penyelarasan.Datadan array menyediakanwithUnsafeBytesuntuk meneruskan penunjuk dan panjang ke C.bindMemorydanassumingMemoryBoundmengatur cara memori mentah diberi tipe.- Urutan bita, penyelarasan, dan keluarnya penunjuk dari fungsi penutupan merupakan bahaya utama.
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
- MemoryLayout dan Alignment
- UnsafePointer dan UnsafeMutablePointer
- Pointer Buffer Tidak Aman
- withUnsafeBytes dan Interoperabilitas C