Cast to different C struct unsafe pointer in Swift
You can write something like this:
withUnsafePointer(to: &sockAddress) {sockaddrInPtr in
sockaddrInPtr.withMemoryRebound(to: sockaddr.self, capacity: 1) {sockaddrPtr in
bind(sock, sockaddrPtr, UInt32(MemoryLayout<sockaddr_in>.stride))
}
}
Or someone suggests this may be better:
withUnsafePointer(to: &sockAddress) {sockaddrInPtr in
let sockaddrPtr = UnsafeRawPointer(sockaddrInPtr).assumingMemoryBound(to: sockaddr.self)
bind(sock, sockaddrPtr, UInt32(MemoryLayout<sockaddr_in>.stride))
}
This article may be some help.
(UPDATE)
As described in the link shown by Martin R, now MemoryLayout<T>.stride
and MemoryLayout<T>.size
return the same value which is consistent with C's sizeof
, where T is an imported C-struct. I'll keep my stride
version of answer here, but that is not something "required" in this case now.
Cast C struct double pointer to a Swift struct unsafe pointer
Let's think about that in terms of what's happening in C. When I do a cast of pointers in C, the data that represents the pointer type will now be treated as a pointer of a different type. The value of the pointer doesn't change, just how you treat it.
Swift doesn't like to do this kind of thing and doesn't encourage you to do it because while cheap, it's a fundamentally unsafe thing to do and can lead to corrupting data, jumping into space, bus errors, etc.
That doesn't mean that swift doesn't have the ability to do this. The link that you point to uses withUnsafePointerTo
which tries to limit the scope of the use of the pointer. In your case, you probably want to look at unsafeBitCast
(documentation here) which mimics the C pointer cast (it's not strictly the same as C casting in general, but for pointers it is).
let a:UnsafeMutablePointer<SomeType> = fetchASomeTypePointer()
let b = unsafeBitCast(a, to: UnsafeMutablePointer<SomeOtherType>.self)
This makes the data representing the pointer to SomeType
now become a pointer to SomeOtherType
.
Like I said before, this is a dangerous thing to do especially if you don't fully understand what you're doing.
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)
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)
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) }
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)
casting address of swift struct to C pointer of specific type
If you declare the struct as a variable
var someData = SomeStruct(someValue: 1)
then you can use withUnsafe(Mutable)Pointer()
to get a pointer:
withUnsafeMutablePointer(&someData) {
myFunc(UnsafeMutablePointer($0), UInt8(sizeof(SomeStruct)))
}
This guarantees that the pointer is only used while the structure is
valid.
If the C function takes a constant pointer
myFunc(const u8* data, u8 lengthOfData);
then you don't need mutable pointers:
withUnsafePointer(&someData) {
myFunc(UnsafePointer($0), UInt8(sizeof(SomeStruct)))
}
But note that the layout of Swift structures is not defined and may
change. For data structures needed in both Swift and C it may be
safer to define them as C structures in the C header files instead.
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
C-style pointer/array casting in Swift?
Let’s assume the byteArray
had eight bytes in it. You could do:
let byteArray: [UInt8] = [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7]
let value = byteArray.withUnsafeBytes {
$0.bindMemory(to: UInt64.self)[0].littleEndian // or .bigEndian
}
Resulting in:
0x0706050403020100 // or 0x0001020304050607 if you use bigEndian
Or, if you had enough bytes for multiple UInt64
, you could do:
let longByteArray: [UInt8] = [
0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
]
let values = longByteArray.withUnsafeBytes {
$0.bindMemory(to: UInt64.self)
}.map {
$0.littleEndian // or .bigEndian
}
Resulting in
[0x0706050403020100, 0x0f0e0d0c0b0a0908] // or [0x0001020304050607, 0x08090a0b0c0d0e0f] if you use bigEndian
Related Topics
Swiftui: How to Only Run Code When the User Stops Typing in a Textfield
Swift 4.2 - _Shared Attribute Near Type
How to Refresh Multiple Timers in Widget iOS14
Saving Dictionary into Nsuserdefaults
Get Compiler Error in Swift Indexof()
Swift 4: Validating Credit Card Expiration Date
How to Use Bit Field with Swift to Store Values with More Than 1 Bit
Swift 3: Int Is Not Convertible to Bool in Bitwise Operation
How to Properly Check If Non-Optional Return Value Is Valid
Parse.Com Pfgeopoint.Geopointforcurrentlocationinbackground Not Doing Anything
How to Create a Circle with Rounded Ends for Each Quadrant
Swift Error Using Initialized Properties in Expressions Before Super.Init
How to Make a Custom Mkannotationview with Xib
How to Segue Values When My Viewcontroller Is Embedded in an Uinavigationcontroller
Drag a Cgrect Using Uipangesturerecognizer
Why There Is a Overflow with Swift Language When Assign a 8 Bits Binary Value to a Var of Int8 Type