【问题标题】:Cast a Swift struct to UnsafeMutablePointer<Void>将 Swift 结构转换为 UnsafeMutablePointer<Void>
【发布时间】:2015-06-15 21:18:39
【问题描述】:

有没有办法将 Swift 结构的地址转换为 void UnsafeMutablePointer?
我试过这个没有成功:

struct TheStruct {
    var a:Int = 0
}

var myStruct = TheStruct()
var address = UnsafeMutablePointer<Void>(&myStruct)

谢谢!

编辑:上下文
我实际上是在尝试将 Learning CoreAudio 中的第一个示例移植到 Swift。
这是我到目前为止所做的:

func myAQInputCallback(inUserData:UnsafeMutablePointer<Void>,
    inQueue:AudioQueueRef,
    inBuffer:AudioQueueBufferRef,
    inStartTime:UnsafePointer<AudioTimeStamp>,
    inNumPackets:UInt32,
    inPacketDesc:UnsafePointer<AudioStreamPacketDescription>)
 { }

struct MyRecorder {
    var recordFile:     AudioFileID = AudioFileID()
    var recordPacket:   Int64       = 0
    var running:        Boolean     = 0
}

var queue:AudioQueueRef = AudioQueueRef()
AudioQueueNewInput(&asbd,
    myAQInputCallback,
    &recorder,  // <- this is where I *think* a void pointer is demanded
    nil,
    nil,
    UInt32(0),
    &queue)

我正在努力留在 Swift 中,但如果结果证明这是一个问题而不是优势,我最终将链接到一个 C 函数。

编辑:底线
如果你是因为试图在 Swift 中使用 CoreAudio 的 AudioQueue 而提出这个问题的......不要。 (详情请阅读 cmets)

【问题讨论】:

  • 你能补充一些信息为什么地址需要作为空指针吗?
  • 当然!我正在尝试在 Swift 中使用 CoreAudio。编译器抱怨传递给 AudioQueueNewInput 的参数不是它们应该是的,而传递的结构 似乎 是造成这种情况的原因。
  • 您应该在问题中添加更多信息和代码。究竟是哪个函数,你如何尝试调用它,确切的错误信息......
  • 谢谢林太郎。如果这是真的,那我就是在浪费时间......为什么Apple的文档中有这个定义? SWIFT typealias AudioQueueInputCallback = CFunctionPointer, AudioQueueRef, AudioQueueBufferRef, UnsafePointer, UInt32, UnsafePointer) -> Void)> 这让我认为,如果你定义一个具有所需的常规函数签名,可以将其作为 AudioQueueInputCallback 传递给 AudioQueueNewInput。
  • Martin 指出的链接中的最后几行可能对我的问题最有用:“对于您不应该尝试在 Swift 中表达的问题,这是一个非常痛苦的解决方法。代码必须操作指针,尤其是函数指针,最好保留在 C 或 Objective-C 文件中。否则,你只是在与语言进行一场不必要的战斗——尤其是因为它对 C 和 Objective-C 互操作性的支持非常好。 "谢谢大家!

标签: swift casting void-pointers unsafe-pointers


【解决方案1】:

据我所知,最短的方法是:

var myStruct = TheStruct()
var address = withUnsafeMutablePointer(&myStruct) {UnsafeMutablePointer<Void>($0)}

但是,你为什么需要这个?如果你想将它作为参数传递,你可以(并且应该):

func foo(arg:UnsafeMutablePointer<Void>) {
    //...
}

var myStruct = TheStruct()
foo(&myStruct)

【讨论】:

  • 第一个变体确实不安全,因为指针可能会在myStruct 的生命周期之外使用。 – 如果需要指针作为 C 函数的参数,那么 withUnsafeMutablePointer(&amp;myStruct) { someCFunction(UnsafeMutablePointer&lt;Void&gt;($0)) } 也是一个选项。
  • 我们可以将UnsafeMutablePointer&lt;TheStruct&gt; 传递为UnsafeMutablePointer&lt;Void&gt;。所以withUnsafeMutablePointer(&amp;myStruct) { someCFunction($0) } 也可以。
  • @MartinR 这就是为什么它在类型名称中有“不安全”:)
  • @Kirsteins:是的,但是(在我看来)在闭包内部使用指针和将指针传递到外部之间仍然存在差异。
【解决方案2】:

随着 Swift 多年来的发展,大部分方法原型都发生了变化。以下是 Swift 5 的语法:

var struct = TheStruct()

var unsafeMutablePtrToStruct = withUnsafeMutablePointer(to: &struct) {
    $0.withMemoryRebound(to: TheStruct.self, capacity: 1) {
        (unsafePointer: UnsafeMutablePointer<TheStruct>) in

        unsafePointer
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多