Unsafe pointers in Swift: Conversion to and from a COpaquePointer (and CFunctionPointer) (Part II, Xcode 6 Beta 6; update Swift 3, Xcode 8)
The unsafe pointers in Swift posts, of which this is the second, are a tentative toe-dipping into the world of connecting Swift with the C functions provided in Apple's Darwin -> C -> stdlib header file. As such, this post is neither exhaustive nor expert, I am simply trying to fill a void where I find little else to work with in my experimentations.
You should read the code found here as if it were written in someone's personal notebook and never use it without first understanding it and satisfying yourself that it works correctly.
COpaquePointer
With all of this in mind, here is my code for today, fulfilling the conversion of an UnsafeMutablePointer to and from a COpaquePointer:let str = "Hello, pointer" let ps = UnsafeMutablePointer<String>.alloc(1) // allocate memory for one String instance ps.initialize(str) // intialize with a value let cps = COpaquePointer(ps) // convert UnsafeMutablePointer to COpaquePointer let nps = UnsafeMutablePointer<String>(cps) // convert COpaquePointer to UnsafeMutablePointer nps.memory // returns "Hello, pointer" ps.destroy() // return pointer to an unintialized state ps.dealloc(1) // deallocate memory
Swift 3 (Xcode 8)
let ps = UnsafeMutablePointer.allocate(capacity: 1) // allocate memory for one String instance ps.initialize(to: str) // intialize with a value let cps = OpaquePointer(ps) // convert UnsafeMutablePointer to COpaquePointer let nps = UnsafeMutablePointer (cps) // convert COpaquePointer to UnsafeMutablePointer nps.pointee // returns "Hello, pointer" ps.deinitialize() // return pointer to an unintialized state ps.deallocate(capacity: 1) // deallocate memory
CFunctionPointer
As usual we can go further and among the Swift types you'll find something called a CFunctionPointer as well. So while we're here we may as well have a go at creating one of those for completeness, because in order to create a CFunctionPointer you need a COpaquePointer from which to initialise it:let a:() -> String = { return "Hello from C" } let p = UnsafeMutablePointer<() -> String>.alloc(1) // allocate memory for function p.initialize(a) // initialize with value let cp = COpaquePointer(p) // convert UnsafeMutablePointer to COpaquePointer let fp = CFunctionPointer<() -> String>(cp) // convert COpaquePointer to CFunctionPointer let ncp = COpaquePointer(fp) // convert CFunctionPointer to COpaquePointer let np = UnsafeMutablePointer<() -> String>(ncp) // convert COpaquePointer to UnsafeMutablePointer np.memory() // calls anonymous function and returns "Hello from C" p.destroy() // return pointer to an unintialized state p.dealloc(1) // deallocate memory
Swift 3, Xcode 8
let a:() -> String = { return "Hello from C" } let p = UnsafeMutablePointer<() -> String>.allocate(capacity: 1) // allocate memory for function p.initialize(to: a) // initialize with value let cp = OpaquePointer(p) // convert UnsafeMutablePointer to COpaquePointer let fp = UnsafeMutablePointer<@convention(c) () -> String>(cp) // convert COpaquePointer to CFunctionPointer let ncp = OpaquePointer(fp) // convert CFunctionPointer to COpaquePointer let np = UnsafeMutablePointer<() -> String>(ncp) // convert COpaquePointer to UnsafeMutablePointer p.move()() // calls anonymous function and returns "Hello from C" and deinitializes p.deallocate(capacity: 1) // deallocate memoryWarning: for education purposes only!
Hi
ReplyDeleteI am trying to call the following Object C method from Swift but can't seem to pass in the string in the correct format. It appears to be expecting an UnsafeMutablePointer. Any help would be appreciated.
+ (BOOL) Check:(NSString* __strong *)postcode