14
votes

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)

2
Can you add some information why the address is needed as a void pointer? - Martin R
Sure! I am trying to use CoreAudio in Swift. The compiler complains that the arguments passed to AudioQueueNewInput are not what they should be, and the struct passed <i>seems</i> to be the cause of that. - popisar
You should add more information and code to the question. Which function exactly, how do you try to call it, the exact error message ... - Martin R
Thanks 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
And 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! - popisar

2 Answers

19
votes

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)
0
votes

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
        }
    }