将Swift结构体转换为UnsafeMutablePointer<Void>

14

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

struct TheStruct {
    var a:Int = 0
}

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

谢谢!

EDIT: 上下文
我正在尝试将《学习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...不要这么做。(阅读评论获取详细信息)


你能添加一些关于为什么需要地址作为void指针的信息吗? - Martin R
当然!我正在尝试在Swift中使用CoreAudio。编译器抱怨传递给AudioQueueNewInput的参数不是应该传递的,而传递的结构似乎是原因。 - popisar
你应该在问题中添加更多的信息和代码。具体是哪个函数,你如何尝试调用它,确切的错误信息... - Martin R
1
谢谢 Rintaro。如果是真的,那我就浪费时间了... 那么为什么苹果文档中有这个定义呢? SWIFT typealias AudioQueueInputCallback = CFunctionPointer<((UnsafeMutablePointer<Void>, AudioQueueRef, AudioQueueBufferRef, UnsafePointer<AudioTimeStamp>, UInt32, UnsafePointer<AudioStreamPacketDescription>) -> Void)> 这让我想到,如果你用所需的签名定义一个常规函数,将其作为 AudioQueueInputCallback 传递给 AudioQueueNewInput 是可能的。 - popisar
2
马丁指向的链接中最后几行可能对我的问题最有用: “这是一种极其痛苦的解决方法,而你不应该试图在Swift中表达这个问题。必须操作指针(特别是函数指针)的代码最好留在C或Objective-C文件中。否则,你只是在与语言进行不必要的斗争,特别是因为它对C和Objective-C的互操作性支持非常好。” 谢谢大家! - popisar
显示剩余6条评论
2个回答

19

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

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

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

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

var myStruct = TheStruct()
foo(&myStruct)

3
第一个变量非常不安全,因为指针可能会在myStruct的生命周期之外被使用。如果指针作为C函数的参数需要使用,则可以考虑使用withUnsafeMutablePointer(&myStruct) { someCFunction(UnsafeMutablePointer<Void>($0)) } - Martin R
我们可以将 UnsafeMutablePointer<TheStruct> 作为 UnsafeMutablePointer<Void> 传递。因此,withUnsafeMutablePointer(&myStruct) { someCFunction($0) } 也可以工作。 - rintaro
1
@MartinR 这就是为什么类型名称中有 "unsafe" 的原因 :) - Kirsteins
1
@Kirsteins:是的,但在我看来,在闭包内部使用指针和将其传递到外部仍然存在差异。 - Martin R

1
多年来,随着Swift的发展,大部分方法原型已经发生了变化。以下是Swift 5的语法:
var struct = TheStruct()

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

        unsafePointer
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接