Interacting with C Pointers in Swift. Part 2

Peter Wood in Swift
01 Aug 2014, 17:08

What’s up?

This is part two, no mistake, though we didn’t have part one. Part one turned to be unnecessary as Apple’s already written about interacting with C pointers here.

In the second part, we’d like to highlight working with pointers to structures and classes. All the examples are from Beta4, because Beta4 and Beta3 underwent changes related to working with pointers.

There’s no direct access to pointers in Swift. But it has several data types for working with pointers.

Let’s have a look at them:

These types are analogs of MyType* and const MyType*

That is:

var pAddr: UnsafePointer<sockaddr_in>

is the analog of:

sockaddr_in *pAddr

Note: To assign value to void pointer, specify parentheses as a type.

That is:

var pVoid:UnsafePointer<()>

is the analog of:

void *pVoid

This type is used for function arguments. It informs ARC that an object should be autoreleased on return.

So, it is the analog of Objective-C lifetime qualifier __autoreleasing.

As an example, let’s see how NSErrorPointer type is declared:

typealias NSErrorPointer = AutoreleasingUnsafePointer<NSError?>

This type to some reason is missing in “Using Swift with Cocoa and Objective-C”, but we can nevertheless see its declaration:

“A wrapper around an opaque C pointer. Opaque pointers are used to represent C pointers to types that cannot be represented in Swift, such as incomplete struct types.”

It is also often used to cast necessary pointer type (UnsafePointer, ConstUnsafePointer).

This type was added in Beta3. It is used for work with pointers to C function. For example, if we have a function of int (*)(int) type, in Swift it will look like this:

CFunctionPointer<(Int32) -> Int32>

Though it has a limitation:
“However, you cannot call a C function pointer or convert a closure to C function pointer type.” (Xcode 6 beta 4 Release Notes)

Hope it will be eliminated in the nearest update.

Let’s see how UnsafePointer/ConstUnsafePointer and COpaquePointer are used, based on getting string with IP address from sockaddr structure. We’ll need it, for example, to get IP address from NSNetService object.

var inetAddress : sockaddr_in  var ipStringBuffer = UnsafePointer<Int8>.alloc(Int(INET_ADDRSTRLEN))  var addr = inetAddress.sin_addr  
inet_ntop(Int32(inetAddress.sin_family),   ConstUnsafePointer<()>(COpaquePointer(&addr)),   ipStringBuffer,   UInt32(INET_ADDRSTRLEN))  

See you.