Быстрое преобразование [UIn16] в UnsafeMutablePointer‹UInt16›

Я пытаюсь преобразовать массив UInt16 в UnsafeMutablePointer<UInt16>, чтобы вызвать функцию C, которая принимает uint16_t * из Swift.

Если бы моей отправной точкой был [UInt8], а пунктом назначения UnsafeMutablePointer<UInt8>, все было бы просто. Я мог бы преобразовать массив в Data, оттуда в NSData, вызвать bytes.assumingMemoryBound, и на этом я (почти) закончил.

Однако, учитывая поставленную задачу, я рассматриваю несколько разных путей. Один из подходов заключается в преобразовании [UInt16] в [UInt8], использовании того же пути данных, что и описанный выше, а затем указании другого типа в вызове assumingMemoryBound.

Однако это оказывается более сложным, чем ожидалось. Есть куча вопросов о том, как преобразовать массив всего из двух UInt8 в один UInt16; Я нашел один вопрос с вопросом, как преобразовать с одного UInt16 на два UInt8, но все это, кажется, становится гораздо более сложным при преобразовании массивов.

Другой подход, который я пробую, состоит в том, чтобы просто взять значение массива [UInt16] и попытаться преобразовать его в UnsafeMutablePointer<UInt16>, используя промежуточный вызов withUnsafeBytes или что-то в этом роде, но в Swift есть куча разных типов указателей, которые просто не совпадают. В частности, вот одна из моих предыдущих попыток:

array.withUnsafeBytes { (pointer: UnsafeRawBufferPointer) -> UnsafeMutablePointer<UInt16> in
    let mutablePointer = UnsafeMutablePointer<UInt16>(mutating: pointer) // error
    return mutablePointer
}

Однако это приводит к следующей ошибке:

Не удается преобразовать значение типа UnsafeRawBufferPointer в ожидаемый тип аргумента UnsafePointer.

Возможно, я просто еще не нашел правильный вопрос или нужную страницу документации, поэтому буду признателен за любые указатели в правильном направлении!


person arik    schedule 02.04.2021    source источник


Ответы (1)


Методы withXXXBytes дают вам необработанные указатели, но здесь вам нужен типизированный указатель. Вместо этого используйте withUnsafeMutableBufferPointer и получите базовый адрес:

arrayOfUInt16.withUnsafeMutableBufferPointer { (bufferPointer) in
    let mutablePointerOfUInt16 = bufferPointer.baseAddress
    // do whatever you want with mutablePointerOfUInt16
    // just don't "store or return the pointer for later use." as the documentation says 
    // because the pointer is only valid within this block
}
person Sweeper    schedule 02.04.2021
comment
Это работает, спасибо! В моем конкретном случае массив является неизменяемым аргументом метода, в котором происходит это преобразование, поэтому вместо этого я использовал withUnsafeBufferPointer. - person arik; 02.04.2021