Инициализатор UnsafePointer<UInt8> в Swift 3

У меня есть класс проверки квитанции, который устарел после выпуска Swift 3. Я исправил некоторые проблемы, но у меня все еще много...

Вот исходный код GitHub, который я использовал: https://gist.github.com/baileysh9/4386ea92b047d97c7285 и https://gist.github.com/baileysh9/eddcba49d544635b3cf5

  1. Первая ошибка:

        var p = UnsafePointer<UInt8>(data.bytes)
    

Броски компилятора: Невозможно вызвать инициализатор для типа UnsafePointer(UInt8) со списком аргументов типа UnsafeRawPointer

  1. Вторая ошибка

    while (ptr < end)
    

Двоичные операторы <нельзя применять к двум операндам UnsafePointer(UInt8)

Заранее большоеспасибо:)

РЕДАКТИРОВАТЬ

Благодаря ответу LinShiwei я нашел решение для объявления UnsafePointer. Он компилируется, но еще не тестировался (потому что другие ошибки не позволяют мне тестировать):

 func getProductIdFromReceipt(_ data:Data) -> String?
{
  let tempData: NSMutableData = NSMutableData(length: 26)!
  data.withUnsafeBytes {
        tempData.replaceBytes(in: NSMakeRange(0, data.count), withBytes: $0)
    }

    var p: UnsafePointer? = tempData.bytes.assumingMemoryBound(to: UInt8.self)

2 ответа

Решение
  1. В Swift 3 вы не можете инициировать UnsafePointer используя UnsafeRawPointer,

    Ты можешь использовать assumingMemoryBound(to:) преобразовать UnsafeRawPointer в UnsafePointer<T>, Как это:

    var ptr = data.bytes.assumingMemoryBound(to: UInt8.self)
    
  2. использование debugDescription или же distance(to:) сравнить два указателя.

    while(ptr.debugDescription < endPtr.debugDescription)
    

    или же

    while(ptr.distance(to:endPtr) > 0)
    

Можно поставить обычный указательный знак i C &перед массивом Int8 или массивом Uint8, чтобы сделать указатель для ввода C-функции. Подобно массиву &aBuffer ниже (но массив данных должен быть сначала скопирован локально, чтобы сохранить контроль над хранилищем данных до завершения операции, в противном случае вы получите ошибку). Вот процедура обработки данных dropInteraction (доставка байтового массива):

func interpretInstanceData(filename: String, Buffer: [UInt8]) -> String {
    var aBuffer = Buffer
    let sInstanceData = String(cString: Ios_C_InterpretInstanceData(filename, &aBuffer, Int32(aBuffer.count)))

Вопрос немного старый. Но поиск в Google решения по теме преобразования быстрого байтового массива в C-указатель (что еще такое UnsafePointer). Этот вопрос произвел фурор. Но я думаю, что этот ответ будет полезен для более поздних версий Swift (которые я использую). Сработало бы даже тогда. Работает в любом виде использования, требующем указателя от swift (просто сначала сделайте массив правильного типа).

Возможно, недавно изменился только на это, без ".bytes." часть:

var p: UnsafePointer = data.assumingMemoryBound(to: UInt8.self)

из оригинала:

var p = UnsafePointer<UInt8>(data.bytes)
Другие вопросы по тегам