[swift-users] Passing a pointer to self to C function
Mike Ferenduros
mike.ferenduros at gmail.com
Fri Sep 30 06:14:20 CDT 2016
The way to do this is via Unmanaged:
let raw = Unmanaged.passUnretained(expat).toOpaque()
gets you an UnsafeMutableRawPointer you can pass into C functions. You can
turn this back into an ExpatSwift with
let expat = Unmanaged<ExpatSwift>.fromOpaque(raw).takeUnretainedValue()
There are also retained variants that will add or remove a reference to the
object in question.
Basically, if you know that the pointer won't outlive the thing it
references, you want the unretained variants. This is usually what you want
when you're wrapping C APIs with callbacks, especially if callbacks happen
synchronously.
On the other hand, if the pointer lives independently of the Whatever then
you may want to
- create the pointer with passRetained(), which will keep the object it
points to alive
- access the object with take*Un*retainedValue() (so you don't prematurely
release your reference to it), and
- call release() on it when you're done with it.
If you forget the 3rd step then you're leaking memory, and if you
miscalculate and do it twice then you crash.
Or if you're just passing a pointer from A to B one time, you can use
passRetained() + takeRetainedValue().
Hope that helps
Mike
On Fri, 30 Sep 2016 at 13:11 John Brownie via swift-users <
swift-users at swift.org> wrote:
> Still working on the expat wrapper. The thing I need to do is to pass a
> pointer to self to be stored in the userData that will be passed to
> callbacks, allowing me to get at the local instance. I did this in Swift
> 2.2 as:
>
> XML_SetUserData(parser, unsafeBitCast(self,
> UnsafeMutablePointer<Void>.self))
>
> The migrator turned this into:
>
> XML_SetUserData(parser, unsafeBitCast(self, to:
> UnsafeMutableRawPointer.self))
>
> but it doesn't work. I don't get an appropriate pointer back in the
> callback that I can turn into what I need.
>
> >From reading the migration documentation, I don't want to use
> unsafeBitCast if at all possible, but I'm not clear what the alternative is.
>
> Also, getting the userData back is something I will need. I currently use:
>
> let theParser = userData!.bindMemory(to: ExpatSwift.self, capacity: 1)
>
> I think that's correct, but I'm not getting a valid object reference.
>
> Any insight is greatly appreciated!
> --
> John Brownie
> In Finland on furlough from SIL Papua New Guinea
> _______________________________________________
> swift-users mailing list
> swift-users at swift.org
> https://lists.swift.org/mailman/listinfo/swift-users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160930/17526684/attachment.html>
More information about the swift-users
mailing list