After doing some testing I looked up the implementation and Unmanaged it is very misleading in how it is behaves and is implemented.
When you call toOpaque() it returns the result of unsafeBitCast(_value, to: UnsafeRawPointer.self). _value is an internal field we can't directly access, in your case it is the c object passed in. So it seems like it isn't returning a proper UnsafeRawPointer struct. If you change your let c = C() into var c = C() you can call withUnsafeMutablePointer(to: &c) { unsafeMutablePointer in print(unsafeMutablePointer) print(rawPointer) } It will print out different values for the 2 pointers even though they should be the same. If you test with withUnsafePointer(to:_:) it will give the closure pointer same address as the unsafeMutablePointer here. If you need an UnsafeMutablePointer<C> you will need to do something like this (the pointer passed in is only considered valid for the lifetime of the closure): let pointer = withUnsafeMutablePointer(to: &c) { return UnsafeMutablePointer<C>($0) } If you are fine to use the UnsafeRawPointer from toOpaque(), you can convert it back into c with: Unmanaged<C>.fromOpaque(rawPointer).takeUnretainedValue() Hopefully this helped a bit. On Sat, Sep 23, 2017 at 4:44 PM, Michael Ilseman via swift-users < swift-users@swift.org> wrote: > > > On Sep 23, 2017, at 3:44 AM, nyg nyg via swift-users < > swift-users@swift.org> wrote: > > > > Hello all, > > > > I'm trying to get an UnsafeMutablePointer from an > > UnsafeMutableRawPointer obtained using the Unmanaged structure: > > > > class C { var foo = 42, bar = "bar" } > > let c = C() > > > > let rawPointer = Unmanaged.passUnretained(c).toOpaque() > > > > I believe that the object ācā is effectively dead from this point onwards. > Did you try putting a use of c later on to guarantee its lifetime? E.g. add > a `dump(c)` at the bottom of your script? > > > let pointer = rawPointer.bindMemory(to: C.self, capacity: 1) > > let pointee = pointer.pointee > > print(pointee.foo) // EXC_BAD_ACCESS > > > > Here's some LLDB output, which looks strange to me as everything seems > > alright in pointer until I ask for its pointee: > > > > (lldb) frame variable -L c > > scalar: (memtest2.C) c = 0x0000000101d00030 { > > 0x0000000101d00040: foo = 42 > > 0x0000000101d00048: bar = "bar" > > } > > (lldb) frame variable -L rawPointer > > 0x00000001005e2e08: (UnsafeMutableRawPointer) rawPointer = { > > scalar: _rawValue = 0x0000000101d00030 { > > 0x0000000101d00040: foo = 42 > > 0x0000000101d00048: bar = "bar" > > } > > } > > (lldb) frame variable -L pointer > > 0x00000001005e2e10: (UnsafeMutablePointer<memtest2.C>) > > pointer = 0x0000000101d00030 > > (lldb) frame variable -L pointer._rawValue > > scalar: (memtest2.C) pointer._rawValue = 0x0000000101d00030 { > > 0x0000000101d00040: foo = 42 > > 0x0000000101d00048: bar = "bar" > > } > > (lldb) frame variable -L pointee > > 0x00000001005e2e18: (memtest2.C) pointee = 0x00000001005b65d8 { > > 0x00000001005b65e8: foo = 140736790071664 > > 0x00000001005b65f0: bar = "" > > } > > > > I've also tried assumingMemoryBound(to:) or simply doing: > > > > let pointer = UnsafePointer<C>(bitPattern: Int(bitPattern: rawPointer))! > > print(pointer.pointee.foo) // EXC_BAD_ACCESS > > > > But I always get this EXC_BAD_ACCESS error. What is going on here? > > > > > > Thanks for your help, > > Nick > > _______________________________________________ > > swift-users mailing list > > swift-users@swift.org > > https://lists.swift.org/mailman/listinfo/swift-users > > _______________________________________________ > swift-users mailing list > swift-users@swift.org > https://lists.swift.org/mailman/listinfo/swift-users >
_______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users