Cast a Swift struct to UnsafeMutablePointer<Void>
Solution 1
As far as I know, the shortest way is:
var myStruct = TheStruct()
var address = withUnsafeMutablePointer(&myStruct) {UnsafeMutablePointer<Void>($0)}
But, why you need this? If you want pass it as a parameter, you can (and should):
func foo(arg:UnsafeMutablePointer<Void>) {
//...
}
var myStruct = TheStruct()
foo(&myStruct)
Solution 2
Most of the method prototypes have been changed as Swift evolved over the years. Here is the syntax for Swift 5:
var struct = TheStruct()
var unsafeMutablePtrToStruct = withUnsafeMutablePointer(to: &struct) {
$0.withMemoryRebound(to: TheStruct.self, capacity: 1) {
(unsafePointer: UnsafeMutablePointer<TheStruct>) in
unsafePointer
}
}
Related videos on Youtube
popisar
Updated on June 04, 2022Comments
-
popisar almost 2 years
Is there a way to cast a Swift struct's address to a void UnsafeMutablePointer?
I tried this without success:struct TheStruct { var a:Int = 0 } var myStruct = TheStruct() var address = UnsafeMutablePointer<Void>(&myStruct)
Thanks!
EDIT: the context
I am actually trying to port to Swift the first example in Learning CoreAudio.
This is what I have done until now: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)
I am doing efforts to stay in Swift, but if this turns out to be more a problem than an advantage, I will end up linking to a C function.
EDIT: bottome line
If you came to this question because you are trying to use a CoreAudio's AudioQueue in Swift... don't. (read the comments for details)-
popisar about 9 yearsThanks rintaro. If it's true, then I am wasting my time... Why then is there this definition in the Apple's doc? SWIFT typealias AudioQueueInputCallback = CFunctionPointer<((UnsafeMutablePointer<Void>, AudioQueueRef, AudioQueueBufferRef, UnsafePointer<AudioTimeStamp>, UInt32, UnsafePointer<AudioStreamPacketDescription>) -> Void)> This lead me to think that, if you define a regular function with the demanded signature, it would be possible to pass it to the AudioQueueNewInput as an AudioQueueInputCallback.
-
popisar about 9 yearsAnd the last lines in the link pointed out by Martin are maybe the most useful to my problem: "It's an incredibly painful workaround for a problem that you shouldn't be trying to express in Swift. Code that must manipulate pointers, especially function pointers, is best left in a C or Objective-C file. Otherwise, you're just fighting an unnecessary battle against the language -especially because it has such great support for C and Objective-C interoperability." Thanks everyone!
-
-
Martin R about 9 yearsThe first variant is really unsafe because the pointer might be used beyond the lifetime of
myStruct
. – If the pointer is needed as an argument to a C function thenwithUnsafeMutablePointer(&myStruct) { someCFunction(UnsafeMutablePointer<Void>($0)) }
is also an option. -
rintaro about 9 yearsWe can pass
UnsafeMutablePointer<TheStruct>
asUnsafeMutablePointer<Void>
. SowithUnsafeMutablePointer(&myStruct) { someCFunction($0) }
also works. -
Kirsteins about 9 years@MartinR That why it has "unsafe" in the type name :)
-
Martin R about 9 years@Kirsteins: Yes, but there is (in my opinion) still a difference between using the pointer inside the closure, and passing it to the outside.