Swift 将数据转换为 UnsafeMutablePointer<Int8>

Swift convert Data to UnsafeMutablePointer<Int8>

我正在从 swift.

调用 objective c class 中的函数
-(char *)decrypt:(char *)crypt el:(int)el{}

当从 swift 调用此函数时,它要求 UnsafeMutablePointer<Int8> 作为参数 'crypt'[=18= 的值]

'crypt' 的值来自服务器,它是一个 base64 编码的字符串。所以我解码了那个字符串并得到了一个数据对象。

let resultData = Data(base64Encoded: base64String)

现在我需要将这些数据传递给上面提到的函数。我试图将此数据对象转换为 UnsafeMutablePointer<Int8>

resultData?.withUnsafeBytes { (u8Ptr: UnsafeMutablePointer<Int8>) in
                    let decBytes = tea?.decrypt(u8Ptr , el: el)}

但它没有编译。给出以下错误

'UnsafeMutablePointer' is not convertible to 'UnsafePointer<_>'

我对objective c了解不多。那么谁能帮我把这个参数传递给 objective c 函数。

您必须将 UnsafeMutablePointer 更改为 UnsafePointer

UnsafePointer

resultData?.withUnsafeBytes {(bytes: UnsafePointer<CChar>)->Void in
            //Use `bytes` inside this closure

        }

UnsafeMutablePointer

 var data2 = Data(capacity: 1024)
data2.withUnsafeMutableBytes({ (bytes: UnsafeMutablePointer<UInt8>) -> Void in
                 //Use `bytes` inside this closure

            })

编辑,更新了我对两件事的回答:

  • 不从 withUnsafeBytes 返回指针
  • 考虑 Swift 5' 弃用警告:'withUnsafeBytes' 已弃用:请改用 withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R
// buffer pointer captured is converted to byte pointer which is used in the block to decode the base64 encoded Data
encodedStringData.withUnsafeMutableBytes { (rawBufferPtr: UnsafeMutableRawBufferPointer) in
    if let rawPtr = rawBufferPtr.baseAddress {
        let decodedString = String(bytesNoCopy: rawPtr, length: rawBufferPtr.count, encoding: .utf8, freeWhenDone: false)
        print(decodedString!)
    }
}
someData.withUnsafeBytes { (bufferRawPtr: UnsafeRawBufferPointer) in
        // For converting an UnsafeRawBufferPointer to its typed variant, in this case UnsafeBufferPointer<UInt8>
            let bufferTypedPtr = bufferRawPtr.bindMemory(to: UInt8.self)

        // Then, getting the typed UnsafePointer, in this case UnsafePointer<UInt8>
            let unsafePointer = bufferTypedPtr.baseAddress!
        }

注意:Swift 5 不允许您从 withUnsafeMutableBytes 块内访问 encodedStringData!阅读 Swift 5 Exclusivity Enforcement why

显然不推荐捕获块外的指针,它可以工作,但将来可能会不确定该行为

旧答案:

这将帮助那些寻求获取 Data 对象的底层原始字节(以 UnsafeMutablePointer<UInt8> 表示)作为 变量 的人进一步使用(而不是必须在 withUnsafeMutableBytes 块中编写所有逻辑)。

var encodedStringData = Data(base64Encoded: "Vmlub2QgaXMgZ3JlYXQh")!
    
// byte pointer variable used later to decode the base64 encoded Data
let rawPtr: UnsafeMutablePointer<UInt8> = encodedStringData.withUnsafeMutableBytes { (bytePtr: UnsafeMutablePointer<UInt8>) in bytePtr }

let decodedString = String(bytesNoCopy: rawPtr, length: encodedStringData.count, encoding: .utf8, freeWhenDone: false)

print(decodedString, encodedStringData)

使用 NSData 的解决方案

let data = NSData(bytes: arrayOfUInt8, length: arrayOfUInt8.count)
let pointer: UnsafeMutablePointer<Int8> = data.bytes.assumingMemoryBound(to: UInt8.self)