在Swift中强制转换为其他C结构不安全指针 [英] Cast to different C struct unsafe pointer in Swift
问题描述
我想从Swift调用Posix套接字函数socket
和bind
. socket
非常简单-需要Int32
s,但是bind
引起了问题,因为我有一个sockaddr_in
指针,但是它需要一个sockaddr
指针.在C语言中,这将是强制转换,例如:
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))
这是Swift中的尝试:
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))
bind
行无法编译为:无法将类型'sockaddr_in'的值转换为预期的参数类型'sockaddr'
如何投射指针?
推荐答案
您可以编写如下内容:
withUnsafePointer(to: &sockAddress) {sockaddrInPtr in
sockaddrInPtr.withMemoryRebound(to: sockaddr.self, capacity: 1) {sockaddrPtr in
bind(sock, sockaddrPtr, UInt32(MemoryLayout<sockaddr_in>.stride))
}
}
或者有人建议这样做可能会更好:
Or someone suggests this may be better:
withUnsafePointer(to: &sockAddress) {sockaddrInPtr in
let sockaddrPtr = UnsafeRawPointer(sockaddrInPtr).assumingMemoryBound(to: sockaddr.self)
bind(sock, sockaddrPtr, UInt32(MemoryLayout<sockaddr_in>.stride))
}
这篇文章可能会有所帮助.
(更新)
如 Martin R 所示的链接所述,现在MemoryLayout<T>.stride
和MemoryLayout<T>.size
返回相同的值,该值与C的sizeof
,其中T是导入的C结构.我将在此处保留答案的stride
版本,但是现在在这种情况下,这不是必需"的内容.
(UPDATE)
As described in the link shown by Martin R, now MemoryLayout<T>.stride
and MemoryLayout<T>.size
return the same value which is consistent with C's sizeof
, where T is an imported C-struct. I'll keep my stride
version of answer here, but that is not something "required" in this case now.
这篇关于在Swift中强制转换为其他C结构不安全指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!