简体   繁体   English

Swift 将数据转换为 UnsafeMutablePointer<Int8>

[英]Swift convert Data to UnsafeMutablePointer<Int8>

I'm calling a function in an objective c class from swift.我正在从 swift 调用目标 c 类中的函数。

-(char *)decrypt:(char *)crypt el:(int)el{}

when calling this function from swift, it asks for an UnsafeMutablePointer<Int8> as the value for the parameter 'crypt'当从 swift 调用这个函数时,它要求一个UnsafeMutablePointer<Int8>作为参数'crypt'的值

the value for the 'crypt' is comming from a server and it is a base64encoded string. 'crypt'的值来自服务器,它是一个 base64 编码的字符串。 So I decode that string and got a Data object.所以我解码了那个字符串并得到了一个 Data 对象。

let resultData = Data(base64Encoded: base64String)

Now I need to pass this data to the above mentioned function.现在我需要将此数据传递给上述函数。 I have tried to convert this Data object to a UnsafeMutablePointer<Int8>我试图将此 Data 对象转换为UnsafeMutablePointer<Int8>

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

But it is not compiling.但它没有编译。 Gives below error给出以下错误

'UnsafeMutablePointer' is not convertible to 'UnsafePointer<_>' “UnsafeMutablePointer”不可转换为“UnsafePointer<_>”

I don't know much about objective c.我对目标c知之甚少。 So could anyone help me to pass this parameter to objective c function.那么任何人都可以帮助我将此参数传递给目标 c 函数。

you have to change UnsafeMutablePointer to UnsafePointer您必须将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

            })

Edit, updated my answer for two things:编辑,更新了我对两件事的回答:

  • Not returning the pointer from withUnsafeBytes不从 withUnsafeBytes 返回指针
  • Accounting for Swift 5' deprecation warning: 'withUnsafeBytes' is deprecated: use withUnsafeBytes<R>(_: (UnsafeRawBufferPointer) throws -> R) rethrows -> R instead考虑 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!
        }

Note: Swift 5 doesn't allow you to access encodedStringData from within the withUnsafeMutableBytes block!注:斯威夫特5不允许访问encodedStringData从内withUnsafeMutableBytes块! Read Swift 5 Exclusivity Enforcement for why .阅读Swift 5 Exclusivity Enforcement了解why

Capturing the pointer outside of the block is apparently not recommended, it works but the behavior can get to be undefined in the future显然不建议在块外捕获指针,它可以工作,但将来可能会不确定该行为

Old answer:旧答案:

This will help someone looking for getting to the underlying raw bytes (in a UnsafeMutablePointer<UInt8> representation) of a Data object as a variable for further use (instead of having to write all of the logic in the withUnsafeMutableBytes block).这将有助于寻找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)

Solution using NSData使用 NSData 的解决方案

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 iOS:转换UnsafeMutablePointer <Int8> swift中的字符串? - iOS: Convert UnsafeMutablePointer<Int8> to String in swift? Swift从UnsafeMutablePointer获取数据<Int8> - Swift get data from UnsafeMutablePointer<Int8> 如何快速将 Int8 转换为 Uint8? - how to convert Int8 to Uint8 in swift? swift 3 iOS:将UInt8数组转换为int8 - swift 3 ios : convert UInt8 Array to int8 如何转换UnsafeMutablePointer <AudioBufferList> 到Swift中的AudioBuffer? - How to convert UnsafeMutablePointer<AudioBufferList> to AudioBuffer in Swift? 如何转换UnsafeMutablePointer <UInt8> 在Swift中使用UIImage - How to convert UnsafeMutablePointer<UInt8> to UIImage in Swift 如何将数组转换为UnsafeMutablePointer <UnsafeRawPointer?> Swift 3.0? - How to convert array to UnsafeMutablePointer<UnsafeRawPointer?> Swift 3.0? 无法使用类型为&#39;(UInt32,UnsafePointer的参数列表&#39;调用&#39;CCHmac&#39; <Int8> ,UInt,[CChar],Int,UnsafeMutablePointer <CUnsignedChar> ) - Cannot invoke 'CCHmac' with an argument list of type '(UInt32, UnsafePointer<Int8>, UInt, [CChar], Int, UnsafeMutablePointer<CUnsignedChar>) 如何快速将数据转换为 Int - how to convert Data to Int in swift 转换UnsafeMutablePointer <CLLocationCoordinate2D> 到Swift中的[CLLocationCoordinate2D] - Convert UnsafeMutablePointer<CLLocationCoordinate2D> to [CLLocationCoordinate2D] in Swift
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM