Last active
July 9, 2024 09:54
-
-
Save dastrobu/ccef82aeb98ab289d94a2cc685ba2e45 to your computer and use it in GitHub Desktop.
Swift Pointer Arithmetic for C Interoperability
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct MyStruct { | |
var n: Int | |
func sayHello() { | |
print("hello") | |
} | |
} | |
var s: MyStruct = MyStruct(n: 1) | |
var a: [UInt8] = [] | |
func takeVoidPtr(_ p: UnsafeMutableRawPointer){ | |
} | |
func takeTypedMyStructPtr(_ p: UnsafeMutablePointer<MyStruct>){ | |
} | |
func takeTypedUInt8Ptr(_ p: UnsafeMutablePointer<UInt8>){ | |
} | |
// void pointers | |
do { | |
let sp = UnsafeMutableRawPointer(&s) | |
let ap = UnsafeMutableRawPointer(&a) | |
// cast to typed | |
let ssp = sp.assumingMemoryBound(to: MyStruct.self) | |
let aap = ap.assumingMemoryBound(to: Array<UInt8>.self) | |
} | |
// typed pointers | |
do { | |
let sp = UnsafeMutablePointer(&s) | |
let ap = UnsafeMutablePointer(&a) | |
// cast to void | |
let ssp = UnsafeMutableRawPointer(sp) | |
let aap = UnsafeMutableRawPointer(ap) | |
// reconstruct object from void pointer | |
let ss = ssp.assumingMemoryBound(to: MyStruct.self).pointee | |
let aa = ssp.assumingMemoryBound(to: Array<UInt8>.self).pointee | |
} | |
// struct pointers safely | |
do { | |
withUnsafeMutablePointer(to: &s) { p in | |
takeVoidPtr(p) | |
} | |
withUnsafeMutablePointer(to: &s) { p in | |
takeTypedMyStructPtr(p) | |
} | |
} | |
// using array pointers safely | |
do { | |
a.withUnsafeMutableBytes { p in | |
takeVoidPtr(p.baseAddress!) | |
} | |
a.withUnsafeMutableBufferPointer { p in | |
takeTypedUInt8Ptr(p.baseAddress!) | |
} | |
// the following would generate a UnsafeMutablePointer<[UInt8]> and does not compile | |
// automatic converstion does not work for withUnsafeMutablePointer | |
// see also https://bugs.swift.org/browse/SR-12442 | |
// withUnsafeMutablePointer(to: &s) { p in | |
// takeTypedUInt8Ptr(p) // Cannot convert value of type 'UnsafeMutablePointer<MyStruct>' to expected argument type 'UnsafeMutablePointer<UInt8>' | |
// } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment