2016-08-17 2 views
3

У меня есть приложение, которое было ранее с помощью UnsafeMutablePointer для вызова C-функции, как так:Проблемы при использовании withMemoryRebound в Swift 3

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) 

После переезда в Swift 3 Xcode Beta 6, Вам будет предложено использовать withMemoryRebound. Проблема в том, что я не понимаю, как ее использовать в этой ситуации, и пока нет документации или образца кода. Моего подход:

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) 

Просто падает с плохим доступом. Каков правильный способ использования withMemoryRebound?

ответ

5

hostInfo является UnsafeMutablePointer<host_basic_info>, и что указатель должен быть «отскок» к указателю HOST_BASIC_INFO_COUNT элементов из integer_t, как и следовало ожидать от hostInfo() функции:

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) 

Вместо allocate/deallocate вы также можете работать с локальных переменные и передать его адрес: с

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) 
0

withMemoryRebound очень похож на функциюUnsafePointer.

Емкость должна быть размером host_info_t.

Вам нужно сделать, как показано ниже:

let temp = hostInfo.withMemoryRebound(to: host_info_t.self or type(of: host_info), capacity: MemoryLayout<host_info_t>.stride * Int(size)) 

кроме того, вам не нужно UnsafeBufferPointer.

0

этот должен работать лучше с быстрым 3

result = withUnsafePointer(to: &size) { 
      $0.withMemoryRebound(to: integer_t.self, capacity: HOST_BASIC_INFO_COUNT) { 
       host_info(machHost, HOST_BASIC_INFO, 
          $0, 
          &size) 
      } 
Смежные вопросы