Swift 3 does not, in general, allow you to convert pointers of one type to pointers of a different type. The rules of the road here are outlined in SE-0107 UnsafeRawPointer API, which puts Swift’s type aliasing rules on a firm footing. I strongly recommend you read the UnsafeRawPointer Migration doc before going further.
In this case,
calloc
returns a raw pointer, that is, a pointer to memory whose type isn’t specified.
String(cString:)
, OTOH, expects a C string pointer, that is, a pointer to a
CChar
, and you can’t just freely cast between the two. You can convert a raw pointer to a typed pointer, but you have to be careful when you do so because it can be very easy to run into aliasing problems. Here’s an example of code that actually compiles.
let cT1 = String(cString: pem_key!.assumingMemoryBound(to: CChar.self))
However, there are better options. My preferred option in situations like this is to allocate the memory with the right type in Swift and then pass its address to the underlying read function. For example.
var buffer = [CChar](repeating: 0, count: keylen)
BIO_read(bio, &buffer, Int32(buffer.count))
let cT1 = String(cString: buffer)
Finally, I have to stress that, if you’re working with a low-level C API like OpenSSL, you’re really going to need to understanding Swift’s pointer rules, as discussed in the docs I referenced above.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"