问题 将Swift结构转换为UnsafeMutablePointer


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

struct TheStruct {
    var a:Int = 0
}

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

谢谢!

编辑:上下文
我实际上是尝试移植到Swift的第一个例子 学习CoreAudio
这是我到目前为止所做的事情:

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函数。

编辑:bottome线
如果你来到这个问题,因为你试图在Swift中使用CoreAudio的AudioQueue ...不要。 (阅读评论了解详情)


6572
2018-04-10 08:21


起源

你能添加一些信息吗? 为什么 地址是否需要作为无效指针? - Martin R
当然!我试图在Swift中使用CoreAudio。编译器抱怨传递给AudioQueueNewInput的参数不是它们应该的,并且传递<i>的结构似乎是</ i>的原因。 - popisar
您应该在问题中添加更多信息和代码。哪个功能完全正确,你如何尝试调用它,确切的错误信息...... - Martin R
谢谢rintaro。如果这是真的,那么我在浪费我的时间......为什么Apple的文档中有这个定义? SWIFT typealias AudioQueueInputCallback = CFunctionPointer <((UnsafeMutablePointer <Void>,AudioQueueRef,AudioQueueBufferRef,UnsafePointer <AudioTimeStamp>,UInt32,UnsafePointer <AudioStreamPacketDescription>) - > Void)>这让我认为,如果你定义了一个需要的常规函数签名,可以将它作为AudioQueueInputCallback传递给AudioQueueNewInput。 - popisar
Martin指出的链接中的最后一行可能对我的问题最有用:“对于一个你不应该试图在Swift中表达的问题,这是一个非常痛苦的解决方法。必须操纵指针的代码,特别是函数指针最好留在C或Objective-C文件中。否则,你只是在与语言进行不必要的斗争 - 特别是因为它对C和Objective-C的互操作性有很大的支持。“感谢大家! - popisar


答案:


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

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

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

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

var myStruct = TheStruct()
foo(&myStruct)

15
2018-04-10 09:31



第一个变体实际上是不安全的,因为指针可能会在生命周期之外使用 myStruct。 - 如果需要指针作为C函数的参数,那么 withUnsafeMutablePointer(&myStruct) { someCFunction(UnsafeMutablePointer<Void>($0)) } 也是一种选择。 - Martin R
我们可以通过 UnsafeMutablePointer<TheStruct> 如 UnsafeMutablePointer<Void>。所以 withUnsafeMutablePointer(&myStruct) { someCFunction($0) }  也有效。 - rintaro
@MartinR为什么它在类型名称中有“不安全”:) - Kirsteins
@Kirsteins:是的,但是(在我看来)在闭包内使用指针并将其传递到外部之间仍有区别。 - Martin R