Cast a Swift struct to UnsafeMutablePointer Void
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)
Cast UnsafeMutablePointer Void to my struct type
Just a guess referencing from here
struct YourStruct {
var name : String
}
var structInstance = YourStruct.init(name: "Jose")
func delegateMethod(voidPtr : UnsafePointer<Void>) {
//CONVERSION HERE
let myStruct = UnsafePointer<YourStruct>(voidPtr).memory
print("\(myStruct.name)")
}
delegateMethod(&structInstance)
How to cast self to UnsafeMutablePointer Void type in swift
An object pointer (i.e. an instance of a reference type) can be
converted to a UnsafePointer<Void>
(the Swift mapping of const void *
, UnsafeRawPointer
in Swift 3) and back. In Objective-C you would write
void *voidPtr = (__bridge void*)self;
//
MyType *mySelf = (__bridge MyType *)voidPtr;
(See 3.2.4 Bridged casts in the Clang ARC documentation for the precise meaning of these
casts.)
Swift has an Unmanaged
type for that purpose.
It is a bit cumbersome to use because it works with COpaquePointer
instead of UnsafePointer<Void>
. Here are two helper methods
(named after the Objective-C __bridge
cast):
func bridge<T : AnyObject>(obj : T) -> UnsafePointer<Void> {
return UnsafePointer(Unmanaged.passUnretained(obj).toOpaque())
// return unsafeAddressOf(obj) // ***
}
func bridge<T : AnyObject>(ptr : UnsafePointer<Void>) -> T {
return Unmanaged<T>.fromOpaque(COpaquePointer(ptr)).takeUnretainedValue()
// return unsafeBitCast(ptr, T.self) // ***
}
The "complicated" expression is only necessary to satisfy Swifts
strict type system. In the compiled code this is just a cast
between pointers. (It can be written shorter as indicated in the ***
comments
if you are willing to use "unsafe" methods, but the compiled
code is identical.)
Using this helper methods you can pass self
to a C function as
let voidPtr = bridge(self)
(or UnsafeMutablePointer<Void>(bridge(self))
if the C function requires
a mutable pointer), and convert it back to an object pointer – e.g.
in a callback function – as
let mySelf : MyType = bridge(voidPtr)
No transfer of ownership takes place, so you must ensure that self
exists as long as the void pointer is used.
And for the sake of completeness, the Swift equivalent of __bridge_retained
and __bridge_transfer
from Objective-C would be
func bridgeRetained<T : AnyObject>(obj : T) -> UnsafePointer<Void> {
return UnsafePointer(Unmanaged.passRetained(obj).toOpaque())
}
func bridgeTransfer<T : AnyObject>(ptr : UnsafePointer<Void>) -> T {
return Unmanaged<T>.fromOpaque(COpaquePointer(ptr)).takeRetainedValue()
}
bridgeRetained()
casts the object pointer to a void pointer and
retains the object. bridgeTransfer()
converts the
void pointer back to an object pointer and consumes the retain.
An advantage is that the object cannot be deallocated between the
calls because a strong reference is held. The disadvantage is that
the calls must be properly balanced, and that it can easily cause retain
cycles.
Update for Swift 3 (Xcode 8):
func bridge<T : AnyObject>(obj : T) -> UnsafeRawPointer {
return UnsafeRawPointer(Unmanaged.passUnretained(obj).toOpaque())
}
func bridge<T : AnyObject>(ptr : UnsafeRawPointer) -> T {
return Unmanaged<T>.fromOpaque(ptr).takeUnretainedValue()
}
func bridgeRetained<T : AnyObject>(obj : T) -> UnsafeRawPointer {
return UnsafeRawPointer(Unmanaged.passRetained(obj).toOpaque())
}
func bridgeTransfer<T : AnyObject>(ptr : UnsafeRawPointer) -> T {
return Unmanaged<T>.fromOpaque(ptr).takeRetainedValue()
}
The relevant changes to "unsafe pointers" are described in
- SE-0017 Change Unmanaged to use UnsafePointer
- SE-0107 UnsafeRawPointer API
Swift casting unsafemutablepointer MyStruct to C void return pointer in swift
look at this 'self explanatory' example
struct MyStruct {
var myId: Int
var myDouble: Double
}
var myStruct = MyStruct(myId: 1, myDouble: 1.0)
// this mimics the funcion which returns Void *myStruct
var vptr = withUnsafeMutablePointer(&myStruct) { (pStruct) -> UnsafeMutablePointer<Void> in
return UnsafeMutablePointer<Void>(pStruct)
}
print(vptr) // 0x00000001079c7828
// mimics mPtr = (MyStruct *) vptr
let mPtr = UnsafeMutablePointer<MyStruct>(vptr) // UnsafeMutablePointer(0x10EE37838)
mPtr.memory.myId = 10
mPtr.memory.myDouble = 10.0
print(myStruct) // MyStruct(myId: 10, myDouble: 10.0)
Typecast UnsafeMutablePointer Void to UnsafeMutablePointer #Struct type#
I think what you want to say is something like this:
imageData = UnsafeMutablePointer<PixelRGB>.alloc(dataLength)
Casting between different UnsafePointer T in swift
struct UnsafePointer<T>
has a constructor
/// Convert from a UnsafePointer of a different type.
///
/// This is a fundamentally unsafe conversion.
init<U>(_ from: UnsafePointer<U>)
which you can use here
doThingsOnRawData(UnsafePointer<UInt8>(data.bytes))
You can even omit the generic type because it is inferred from the context:
doThingsOnRawData(UnsafePointer(data.bytes))
Update for Swift 3: As of Xcode 8 beta 6, you cannot convert
directly between different unsafe pointers anymore.
For data: NSData
, data.bytes
is a UnsafeRawPointer
which can
be converted to UnsafePointer<UInt8>
with assumingMemoryBound
:
doThingsOnRawData(data.bytes.assumingMemoryBound(to: UInt8.self))
For data: Data
it is even simpler:
data.withUnsafeBytes { doThingsOnRawData($0) }
How do you convert a UnsafeMutablePointer Void to UInt8?
You have to convert the pointer to the correct type first
(a pointer to UInt8
) and then you can access the memory it points to:
let u8 = UnsafePointer<UInt8>(theUnsafeMutablePointerVar).memory
In Swift 3, a void pointer from C is imported to Swift as UnsafeMutableRawPointer
, and one can read the pointed-to data
with
let u8 = theUnsafeMutablePointerVar.load(as: UInt8.self)
Swift 2 - UnsafeMutablePointer Void to object
This should work: pass the object pointer as an opaque unmanaged pointer
to the callback:
context.info = UnsafeMutablePointer(Unmanaged.passUnretained(myObject).toOpaque())
SCNetworkReachabilitySetCallback(reachability, callback, &context)
and retrieve in the callback via:
func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>) {
let myObject = Unmanaged<MyObject>.fromOpaque(COpaquePointer(info)).takeUnretainedValue()
}
Of course this assumes that some strong reference to the object exists
as long as the callback is installed, so that the object is not
deallocated.
Update: Note that both conversions from object pointer to void pointer
and back can be simplified if you are willing to use "unsafe" functions:
context.info = unsafeAddressOf(myObject)
// ...
myObject = unsafeBitCast(info, MyObject.self)
The generated assembly code is – as far as I can see – identical.
Update 2: See also How to cast self to UnsafeMutablePointer<Void> type in swift for more information
about the "bridging" and some helper functions which can be used here.
Swift 3 update (Xcode 8 beta 6):
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
context.info = UnsafeMutableRawPointer(Unmanaged.passUnretained(self).toOpaque())
// ...
func callback(reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) {
if let info = info {
let myObject = Unmanaged<MyObject>.fromOpaque(info).takeUnretainedValue()
// ...
}
}
How to convert 'void *' return from a C function to 'UnsafeMutableRawPointer' in Swift 3?
As you may have already found out, Swift 3 attempts to provide better type safety when it comes to pointers. UnsafeMutablePointer
can now only represent a pointer to an instance of a known type. In Swift 2, a C void *
was represented by UnsafeMutablePointer<Void>
, allowing void and non-void pointers to be treated in the same way, including trying to call a de-initializer of the pointed-to type, which is what the destroy()
method in the problematic line of code does:
(ud.userdataPointer() as UnsafeMutablePointer<Void>).destroy()
In Swift 3 the de-initializer on the pointee is called using the deinitialize()
method of the UnsafeMutablePointer
structure. It appears that the migration assistant got confused. The line
(ud.userdataPointer() as UnsafeMutableRawPointer).deinitialize()
makes little sense because (1) UnsafeMutablePointer
cannot be converted using as
to UnsafeMutableRawPointer
;
(2) UnsafeMutableRawPointer
has not deinitialize()
method. In Swift 3, UnsafeMutableRawPointer
is a special type to represent void*
. It is actually quite understandable why the migration tool made this mistake: it blindly replaced destroy()
with deinitialize()
and UnsafeMutablePointer<Void>
with the corresponding Swift 3 type UnsafeMutableRawPointer
, without realizing that the conversion would not work.
I don't quite understand why calling destroy()
on a void pointer would work in Swift 2. Maybe this was a bug in the program or some compiler trick allowed the correct de-initializer to be called. Without knowing enough about the code, I can't be more specific than to suggest analyzing it to figure out what is the type pointed to by that pointer on which destroy()
was called. For example, if we know for sure that it is always the placeholder type T
used on the following line:
let o: T = ud.toCustomType()
then the offending line simply becomes
(ud.userdataPointer() as UnsafeMutablePointer<T>).deinitialize()
We need the conversion in the parentheses to allow the compiler to infer the generic parameter.
Thank you for bringing up an interesting problem. BTW, once you get over this obstacle, you are likely to run into other problems. One thing that jumps out is that UnsafeMutablePointer
has no .memory
in Swift 3; you'll have to use .pointee
instead.
Here's an update. After playing with Swift 2.2 on Linux, I realize that calling destroy()
on an UnsafeMutablePointer<A>
cast as UnsafeMutablePointer<Void>
won't call A's deinitializer, even if it has one. So, you have to be careful with that line...
Related Topics
Using Non Ns_Enum Objective-C Enum in Swift
Vertically Aligning Text in an Nstextfield Using Swift
Nstimer Does Not Invoke a Private Func as Selector
Retrieve String Value from Function with Closure in Swift
Swift: Optional Text in Optional Value
Arkit - Viewport Size VS Real Screen Resolution
Swift Error Handling for Methods That Do Not Throw
How to Create a String from Utf8 in Swift
Rxswift Merge Different Kind of Observables
Why Can't We Use Protocol 'Encodable' as a Type in the Func
How Is Optional Binding Used in Swift
How to Get Random Element from a Set in Swift
Why Can't the Swift Compiler Infer This Closure's Type
Implementing Nscopying in Swift with Subclasses
Are Lazy Vars in Swift Computed More Than Once