I have an app that was previously using UnsafeMutablePointer
to call C-functions like so:
var size = HOST_BASIC_INFO_COUNT
let hostInfo = host_basic_info_t.allocate(capacity: 1)
let result = host_info(machHost, HOST_BASIC_INFO,
UnsafeMutablePointer(hostInfo), &size)
Since moving to Swift 3, Xcode Beta 6 you are prompted to use withMemoryRebound
. Problem is I don't understand how to use it in this situation, and there is no documentation or sample code for it yet.
My approach:
var size = HOST_BASIC_INFO_COUNT
let hostInfo = host_basic_info_t.allocate(capacity: 1)
let temp = hostInfo.withMemoryRebound(to: host_info_t!.self, capacity: Int(size)) {
UnsafeBufferPointer(start: $0, count: Int(size))
}
let result = host_statistics(machHost,
HOST_BASIC_INFO,
temp.baseAddress?.pointee,
&size)
Simply crashes with Bad Access. What is the correct way to use withMemoryRebound
?
hostInfo
is a UnsafeMutablePointer<host_basic_info>
, and that pointer
must be "rebound" to a pointer to HOST_BASIC_INFO_COUNT
items
of integer_t
, as expected by the hostInfo()
function:
let HOST_BASIC_INFO_COUNT = MemoryLayout<host_basic_info>.stride/MemoryLayout<integer_t>.stride
var size = mach_msg_type_number_t(HOST_BASIC_INFO_COUNT)
let hostInfo = host_basic_info_t.allocate(capacity: 1)
let result = hostInfo.withMemoryRebound(to: integer_t.self, capacity: HOST_BASIC_INFO_COUNT) {
host_info(mach_host_self(), HOST_BASIC_INFO, $0, &size)
}
print(result, hostInfo.pointee)
hostInfo.deallocate(capacity: 1)
Instead of allocate/deallocate
you can also work with a
local variable and pass its address:
let HOST_BASIC_INFO_COUNT = MemoryLayout<host_basic_info>.stride/MemoryLayout<integer_t>.stride
var size = mach_msg_type_number_t(HOST_BASIC_INFO_COUNT)
var hostInfo = host_basic_info()
let result = withUnsafeMutablePointer(to: &hostInfo) {
$0.withMemoryRebound(to: integer_t.self, capacity: Int(size)) {
host_info(mach_host_self(), Int32(HOST_BASIC_INFO), $0, &size)
}
}
print(result, hostInfo)
this one should work better with swift 3
result = withUnsafePointer(to: &size) {
$0.withMemoryRebound(to: integer_t.self, capacity: HOST_BASIC_INFO_COUNT) {
host_info(machHost, HOST_BASIC_INFO,
$0,
&size)
}
withMemoryRebound is very similar to withUnsafePointer function.
capacity need to be size of host_info_t.
You need to do like below :
let temp = hostInfo.withMemoryRebound(to: host_info_t.self or type(of: host_info), capacity: MemoryLayout<host_info_t>.stride * Int(size))
additionally, you don't need UnsafeBufferPointer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With