//基本指針 UnsafePointer<T> const T * UnsafeMutablePointer T * //集合指針 UnsafeBufferPointer const T * //指向一個連續已知類型區域,可以看成一個集合,並支持集合操作 UnsafeMutableBufferPointer T * //指向一個連續已知類型區域,可以看成一個集合,並支持集合操作 //空指針 UnsafeRawPointer const void * UnsafeMutableRawPointer void * UnsafeRawBufferPointer const void * //指向一個連續未知類型區域 UnsafeMutableRawBufferPointer void * //指向一個連續未知類型區域
//UnsafePointer參數只能接收inout修飾的類型,而inout修飾的類型必然是可寫的,所以參數只能用var定義 func call(_ p: UnsafePointer<Int>) { print("\(p.pointee)") } var a = 1234 //&a用於傳遞指針 call(&a) // 打印:1234
func modify(_ p: UnsafeMutablePointer<Int>) { p.pointee = 5678 } var a = 1234 modify(&a) print("\(a)") // 打印:5678
let a: [Int32] = [1, 2, -1, -2, 5, 6] let p = a.withUnsafeBufferPointer { $0 } print("\(p.count)") // 打印:6 print("\(p[3])") // 打印:-2
let rp: UnsafeMutablePointer<CChar> = rRes.value let strLength = rRes.length //將UnsafeMutablePointer<CChar> C語言的char *指針轉成 UnsafeMutableRawPointer 的void *任意指針。然後直接取出封裝成String字符串 let strRes = String.init(bytesNoCopy: UnsafeMutableRawPointer(mutating: rp), length: Int(strLength), encoding: .utf8, freeWhenDone: false)
UnsafePointer 基本指針 //將指針的類型轉換成一個臨時的給定類型,並將指針傳遞給closure func withMemoryRebound<T, Result>(to: T.Type, capacity: Int, (UnsafePointer<T>) -> Result) -> Result //向下移動一位,並返回一個新的指針 func successor() -> UnsafePointer<Pointee> //向上移動一位,並返回一個新的指針 func predecessor() -> UnsafePointer<Pointee> RawPointer 空指針 //轉換給指定類型的指針 func assumingMemoryBound<T>(to: T.Type) -> UnsafeMutablePointer<T> //轉換成指定類型的指針,capacity指定了這個指針讀取的T數據數量 func bindMemory<T>(to type: T.Type, capacity count: Int) -> UnsafeMutablePointer<T> UnsafeBufferPointer 集合指針 let rpSub:UnsafeMutablePointer<UInt8> = rp.withMemoryRebound(to: UInt8.self, capacity: Int(strLength), { $0 }) let buffer = UnsafeBufferPointer<UInt8>.init(start: rpSub, count: Int(strLength))
//返回一個T類型指針。將第一個參數T以指針的形式傳遞給closure func withUnsafePointer<T, Result>(to: T, (UnsafePointer<T>) -> Result) -> Result func withUnsafePointer<T, Result>(to: inout T, (UnsafePointer<T>) -> Result) -> Result func withUnsafeMutablePointer<T, Result>(to: inout T, (UnsafeMutablePointer<T>) -> Result) -> Result func withUnsafePointer<T, Result>(to value: inout T, _ body: (UnsafePointer<T>) throws -> Result) rethrows -> Result
var a = 1234 let p = withUnsafePointer(to: &a) { $0 } print("\(p.pointee)") // 打印:1234
var a: UInt32 = 0x12345678 let p = withUnsafeBytes(of: &a) { $0 } var log = "" for item in p { let hex = NSString(format: "%x", item) log += "\(hex)" } print("\(p.count)") // 打印:4 print("\(log)") // 對於小端機器會打印:78563412
let p = UnsafeMutablePointer<Int32>.allocate(capacity: 1) p.initialize(to: 0) // 初始化 p.pointee = 32 print("\(p.pointee)") // 打印:32 p.deinitialize(count: 1) // 反初始化 p.deallocate()
var n = 10086 // malloc let p = malloc(MemoryLayout<Int32>.size)! // memcpy memcpy(p, &n, MemoryLayout<Int32>.size) let p2 = p.assumingMemoryBound(to: Int32.self) print("\(p2.pointee)") // 打印:10086 // strcpy let str = "abc".cString(using: .ascii)! if str.count != MemoryLayout<Int32>.size { return } let pstr = p.assumingMemoryBound(to: CChar.self) strcpy(pstr, str) print("\(String(cString: pstr))") // 打印:abc // strlen print("\(strlen(pstr))") // 打印: 3 // memset memset(p, 0, MemoryLayout<Int32>.size) print("\(p2.pointee)") // 打印:0 // strcat strcat(pstr, "h".cString(using: .ascii)!) strcat(pstr, "i".cString(using: .ascii)!) print("\(String(cString: pstr))") // 打印:hi // strstr let s = strstr(pstr, "i")! print("\(String(cString: s))") // 打印:i // strcmp print("\(strcmp(pstr, "hi".cString(using: .ascii)!))") // 打印:0 // free free(p)
let rRes = c_shmread() let rp: UnsafeMutablePointer<CChar> = rRes.value let strLength = rRes.length //1.先將UnsafeMutablePointer<CChar> C語言的char *指針轉成 UnsafeMutableRawPointer 的void *任意指針。然後直接取出封裝成String字符串 if let strRes = String.init(bytesNoCopy: UnsafeMutableRawPointer(mutating: rp), length: Int(strLength), encoding: .utf8, freeWhenDone: false) { return strRes } else { return "" } //2.使用withMemoryRebound轉換指針類型從CChar轉成UInt8類型; let rpSub:UnsafeMutablePointer<UInt8> = rp.withMemoryRebound(to: UInt8.self, capacity: Int(strLength), { $0 }) //然後創建集合類型指針UnsafeBufferPointer; let buffer = UnsafeBufferPointer<UInt8>.init(start: rpSub, count: Int(strLength)) buffer.forEach { print($0) } //然後創建Data, 再將data轉成String let data = Data(bytes: rpSub, count: Int(strLength)) let str = String(data: data, encoding: String.Encoding.utf8)