Most Swift developers are familiar with how great Swift is at integrating with Objective-C, but what about C itself? Today we'll look at how we can interact with C variables and pointers in Swift. Let's dive in.

Here's a few variables in C:

const int *someInt
int *anotherInt
struct Spaceship *spaceship

When referenced in Swift, these become:

UnsafePointer<Int>
UnsafeMutablePointer<Int>
COpaquePointer

What about those pesky void pointers in C?

void launchSpaceshipWithID(const void *spaceshipID);

Buckle up, for this we'll need to go unsafe...

Swift tries its best to keep us safe, so for something like void pointers, we'll need to jump through a few safety-defying hoops:

var sID = 31
withUnsafePointer(&sID) { (p: UnsafePointer<Int>) in
  let voidP = unsafeBitCast(p, UnsafePointer<Void>.self)
  launchSpaceshipWithID(voidP)
}

First we create a regular Int value in Swift. Nothing special. Then, we'll pass it in to the withUnsafePointer function, along with a closure. Inside, we'll be passed in an UnsafePointer version of our original Int. We'll use the unsafeBitCast function to convert it into to a void pointer. Finally, we'll pass it in the C function. Whew!