I'm trying to do some network code in swift and the type checking is giving me fits.
var sock: CInt = ...
var rin: sockaddr_in
var rlen = socklen_t(sizeof(sockaddr_in))
var buffer: CChar[] = CChar[](count: 128, repeatedValue: 0)
let len = recvfrom(sock, &buffer, 128, 0, &rin, &rlen)
The compiler complains (very cryptically) at the recvfrom
about the fact that &rin
is a pointer to sockaddr_in
instead of sockaddr
. I tried various ways to convert the pointer type, but I can't seem to get this right.
If I declare it to be a sockaddr
I can get this to compile, but then I can't look at it as a sockaddr_in
.
Update for Swift 3 and later, compare UnsafeRawPointer Migration:
var sock: CInt = 1234
var rin = sockaddr_in()
var rlen = socklen_t(MemoryLayout.size(ofValue: rin))
var buffer = [CChar](repeating: 0, count: 128)
let len = withUnsafeMutablePointer(to: &rin) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {
recvfrom(sock, &buffer, buffer.count, 0, $0, &rlen)
}
}
Update: As of Swift 1.2 (Xcode 6.3 beta), initializing a C struct has become much simpler:
var rin = sockaddr_in()
defines a sockaddr_in
variable and initializes all elements to zero.
The conversion of a address of sockaddr_in
to an an address of
sockaddr
is done as follows:
let len = withUnsafeMutablePointer(&rin) {
recvfrom(sock, &buffer, UInt(buffer.count), 0, UnsafeMutablePointer($0), &rlen)
}
Old answer: The first problem is that the sockaddr_in
variable has to be initialized before
its address can be passed to recvfrom()
. Initializing complex structs in Swift
seems to be clumsy, compare
Using the helper function from https://stackoverflow.com/a/24335355/1187415:
func initStruct<S>() -> S {
let struct_pointer = UnsafeMutablePointer<S>.alloc(1)
let struct_memory = struct_pointer.move()
struct_pointer.dealloc(1)
return struct_memory
}
the socket address can be initialized as
var rin : sockaddr_in = initStruct()
To cast the sockaddr_in
pointer to a sockaddr
pointer, use reinterpretCast()
.
let len = recvfrom(sock, &buffer, UInt(buffer.count), 0, reinterpretCast(&rin), &rlen)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With