1

When interacting with a C api (the SQLite 3 C api) from Swift, I need to pass a pointer to a pointer to const char as an out-parameter:

sqlite3_prepare_v2(
// snip other parameters
const char **pzTail // OUT parameter
);

Which is translated into Swift as:

sqlite3_prepare_v2(
// snip other parameters
UnsafeMutablePointer<UnsafePointer<Int8>>
)

This out parameter wants to end up usable as a string. You can pass a Swift String to a const char * easily, but I don't understand how to get something usable from the double-indirection.

Can anyone shed some light here?

Ben
  • 542
  • 1
  • 5
  • 12
  • You could check the source code of GRDB.swift https://github.com/groue/GRDB.swift/blob/master/GRDB/Core/Statement.swift#L45 – Gwendal Roué Dec 06 '15 at 16:52

1 Answers1

2

I had a bit of fun playing around with this. I haven't touched any of the C-Swift stuff before

Here is what I have achieved in a playground. Hope it helps you :)

Edit: I made a better pure swift version

// Function to convert your type - UnsafeMutablePointer<UnsafePointer<Int8>>
func stringFromYourType(cStringPointer: UnsafeMutablePointer<UnsafePointer<Int8>>) -> String? {
    guard let string = String.fromCString(cStringPointer.memory) else { return nil }
    return string
}

// Create your type
let swiftString = "I'm a swift string"
var pointer = swiftString.nulTerminatedUTF8.withUnsafeBufferPointer { UnsafePointer<Int8>($0.baseAddress) }

// Convert it back
var newSwiftString = stringFromYourType(&pointer) // &pointer is equivalent to (char **)
Adam Campbell
  • 646
  • 5
  • 13