在Swift中强制转换为其他C结构不安全指针 [英] Cast to different C struct unsafe pointer in Swift

查看:121
本文介绍了在Swift中强制转换为其他C结构不安全指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从Swift调用Posix套接字函数socketbind. 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 Int32s, 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>.strideMemoryLayout<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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆