withUnsafeMutablePointer to Any Type

let size = MemoryLayout<GPRS_BASE_INFO>.size

print("size = (size)")

var a:Any = GPRS_BASE_INFO()
var b = GPRS_BASE_INFO()

b.addr.1 = 100

let aPtr = withUnsafeMutablePointer(to: &a){$0.withMemoryRebound(to: UInt8.self, capacity: size){$0}}
let bPtr = withUnsafeMutablePointer(to: &b){$0.withMemoryRebound(to: UInt8.self, capacity: size){$0}}

aPtr.assign(from: bPtr, count: size)

print(a)

GPRS_BASE_INFO is a c struct type
help this program will broken when print a variable
i think it should be unwrapped to right Type when using withUnsafeMutablePointer
or is it forbidden?

The way ensure that a has the same layout as b is to convert it to the same GPRS_BASE_INFO type.

let aCopy = a as! GPRS_BASE_INFO

withUnsafeMutablePointer gives you a temporary view of a value via a pointer that is only valid within the closure body as stated in the function's documentation:

The pointer argument is valid only for the duration of the function's
execution.

withMemoryRebound gives you a temporary view of memory as a different type via a pointer that is only valid within the closure body:

The closure's pointer argument is valid only for the duration of the closure's execution.

withMemoryRebound is generally useful to call out to a C API that uses pointer types inconsistently. It's always preferable to rewrite the C APIs or add a wrapper so that you never need to "bind" memory in Swift land.

1 Like

i think it will make code hard to read if there are two or more pointers,
so i take it out of clouser

thanks

extension ArraySlice where Element == UInt8 {
    public func getUInt<T:FixedWidthInteger>(offset:Int) -> T? {
        let count = T.bitWidth >> 3
        guard self.count >= count + offset else {
            return nil
        }
        
        var b:T = 0
        for i in 0..<count {
            b |= T(self[i + offset]) << (i * 8)
        }
        return b
    }
}

and this is another problem
the extension function will broken sometimes and report out of bouds error

then i change it to :
public func getUInt<T:FixedWidthInteger&UnsignedInteger>(offset:Int) -> T?

and it seems work ok , but i worry it will broken again
is it ok? thanks again

Unfortunately, you can't do that. The pointer is invalid outside of the closure.

It sounds like there may be a bug in the standard library. I wouldn't expect the UnsignedInteger constraint to affect the behavior of arithmetic. cc @scanon

oh got it!
i will fix it in my code by next time.

Oh ,I found that ArraySlice has startIndex property.
I think it is begin with position 0,
it's much Inconvenient to use with a startIndex.

Yeah, you can see some discussion of why in this thread.