I want to call the Posix socket functions socket
and bind
from Swift. socket
is pretty easy—it takes Int32
s, but bind
is causing a problem, because I have a sockaddr_in
pointer, but it wants a sockaddr
pointer. In C, this would be a cast, like:
bind(sock, (struct sockaddr *)&sockAddress, sizeof(sockAddress))
Here's an attempt in Swift:
let sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)
var sockAddress = sockaddr_in()
bind(sock, &sockAddress, UInt32(MemoryLayout<sockaddr_in>.size))
The bind
line fails to compile with: cannot convert value of type 'sockaddr_in' to expected argument type 'sockaddr'
How do I cast the pointer?
In Swift 3 you have to "rebind" the pointer (compare SE-0107 UnsafeRawPointer API):
Remarks:
The type annotations in
let sock: Int32
andvar sockAddress: sockaddr_in
are not needed.The
memset()
is not necessary becausesockaddr_in()
initializes all struct members to zero.The Swift equivalent of the C(This "problem" does not exist anymore. For structs imported from C,sizeof
isstride
(which includes a possible struct padding), notsize
(which does not include the struct padding).stride
andsize
have the same value.)You can write something like this:
Or someone suggests this may be better:
This article may be some help.
(UPDATE) As described in the link shown by Martin R, now
MemoryLayout<T>.stride
andMemoryLayout<T>.size
return the same value which is consistent with C'ssizeof
, where T is an imported C-struct. I'll keep mystride
version of answer here, but that is not something "required" in this case now.