[swift-users] Pointer conversions between different sockaddr types
Martin R
martinr448 at gmail.com
Wed Aug 17 12:55:19 CDT 2016
I am trying to figure out how to work correctly with the new UnsafeRawPointer API (from https://github.com/apple/swift-evolution/blob/master/proposals/0107-unsaferawpointer.md ).
Here my concrete example: The connect() system call takes a (const struct sockaddr *address) parameter, but one actually passes the address of a struct sockaddr_in or sockaddr_in6 (or ...).
In Swift 2.2 this could be done as
var addr = sockaddr_in() // or sockaddr_in6()
// fill addr fields ...
let sock = socket(PF_INET, SOCK_STREAM, 0)
let result = withUnsafePointer(&addr) {
connect(sock, UnsafePointer($0), socklen_t(strideofValue(addr)))
}
With the latest Swift from Xcode 8 beta 6, unsafe pointers cannot be simply initialized from a different kind of unsafe pointer anymore. I came up with two different solutions:
let result = withUnsafePointer(to: &addr) {
connect(sock,
UnsafeRawPointer($0).assumingMemoryBound(to: sockaddr.self),
socklen_t(MemoryLayout<sockaddr_in>.stride))
}
or
let result = withUnsafePointer(to: &addr) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
connect(sock, $0, socklen_t(MemoryLayout<sockaddr_in>.stride))
}
}
which both compile and run correctly.
My questions are:
- Are both solutions correct, should one be preferred, or are both wrong?
- Can the same be achieved simpler?
Thanks,
Martin
More information about the swift-users
mailing list