How do I get a pointer to self

I need to get a pointer to self which is passed to a C function. The C API will later call a callback method and pass back this reference which I can then use to get an instance to my class back.


The code below shows a simple example of what I am trying to do. ptrToSelf() should return an UnsafeMutableRawPointer which I can then pass to the C function. This is later on used to get the instance to the class back.


I can get a pointer to the instance of my class, but not to self.

What should I do in the implementation of ptrToSelf()?


class MyClass {
  func doSometing() {
    print("I'm trying.")
  }

  func ptrToSelf() -> UnsafeMutableRawPointer {
    return Unmanaged.passUnretained(self).toOpaque()
  }
}

var myClass = MyClass()
//let rawPtr = UnsafeMutableRawPointer(&myClass) // <-- This works.
let rawPtr = myClass.ptrToSelf()                 // <-- This does not work.
let classPtr = rawPtr.bindMemory(to: MyClass.self, capacity: 1)
classPtr.pointee.doSometing()

Accepted Reply

I need to get a pointer to self which is passed to a C function. The C API will later call a callback method and pass back this reference which I can then use to get an instance to my class back.

You have the first part of this right but you’re definitely off in the weeds with regards the second part. You can find instructions for fixing that in this post.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

I tried your code, with the following.

        var myClass = MyClass()
        let rawPtr = UnsafeMutableRawPointer(&myClass) /
        let rawPtr2 = myClass.ptrToSelf()                 // just to log, not used
        let classPtr = rawPtr.bindMemory(to: MyClass.self, capacity: 1)
        let classPtr2 = rawPtr2.bindMemory(to: MyClass.self, capacity: 1)
        classPtr.pointee.doSometing()

What I get :

myClass:

<MyClass: 0x60c00000c990>


rawPtr:

(UnsafeMutableRawPointer) rawPtr = <variable not available>


rawPtr2:

▿ 0x000060c00000c990

- pointerValue : 106377750038928


Surprising that

rawPtr2 seems to point to myClass but does not work

rawPtr seems to point to nothing but works !


But it appears that

- classPtr.pointee is valid

- classPtr2.pointee is not valid (bad memory access): why ?


IF YOU CHANGE like this :

    func ptrToSelf() -> UnsafeMutableRawPointer {
        var mySelf = self
        return UnsafeMutableRawPointer(&mySelf)
    }


That works


See discussion here :

h ttps://stackoverflow.com/questions/33294620/how-to-cast-self-to-unsafemutablepointervoid-type-in-swift

You've answered my question but it does not solve my problem.


I agree, it is strange that the one with the same pointer value does not seem to work while the one with a different one does. What we are seeing must not be the entire story so I guess it means falling in to asm a bit to try and understand what is going on.


Why my problem remains: My example given in this post was simple in order to show my problem. When I fix it as you mention, then this example does work BUT when I pass that same pointer to my C function and then get that same pointer back with my C callback and binding it back to my class does not work and gives an exception. My class is still alive, at the same momory location and all the pointers that I look at have the correct values but I still get an exception as soon as I dereference my class.

I need to get a pointer to self which is passed to a C function. The C API will later call a callback method and pass back this reference which I can then use to get an instance to my class back.

You have the first part of this right but you’re definitely off in the weeds with regards the second part. You can find instructions for fixing that in this post.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks Quinn, that solved my problem.


I could still not find anything in the Swift documentation, as you mentioned in your other post. Given how much time I've spent on forums with this, and seeing how many people are struggling with the same problem, it may be worth-while raising that bug and adding it to the docs in a more prominent way.

… that solved my problem.

Cool. Please change the ‘correct answer’ marker for the benefit of future folks reading the thread.

I could still not find anything in the Swift documentation … it may be worth-while raising that bug and adding it to the docs in a more prominent way.

Indeed. We track documentation bugs like we track any other bugs, so you should put that feedback into a bug. It would be a perfect addition to the Interacting with C APIs section of Using Swift with Cocoa and Objective-C.

Please post your bug number, just for the record.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Raised 39720999 as a documentation bug and added a point to this thread in the bug report.