我Data
在这里不使用– Data
表示“原始”字节的未类型化集合,但是crypto_generichash_keygen
想要一个可变的指向类型化 内存的指针。不推荐使用的UnsafeMutablePointer<T>
变体的原因withUnsafeMutableBytes
是,从根本上讲,为无类型内存提供错误的抽象。
在Swift中获取类型化内存缓冲区的最简单方法是使用Array
:
var k = [UInt8](repeating: 0, count: crypto_generichash_keybytes())
Flutter_sodium.crypto_generichash_keygen(&k)
之后,您总是可以Data
通过说出将结果缓冲区变成一个值Data(k)
。
另一种选择是使用UnsafeMutableBufferPointer
:
let k = UnsafeMutableBufferPointer<UInt8>.allocate(capacity: crypto_generichash_keybytes())
defer {
k.deallocate()
}
Flutter_sodium.crypto_generichash_keygen(k.baseAddress!)
// Now use the buffer `k` – just make sure you finish using it before the end of
// the scope when `deallocate()` gets called!
与不同Array
,这避免了在传递给C API之前不必用0预填充结果缓冲区,但是这可能不必担心。但就像Array
,你可以把这样的缓冲成Data
通过只是说Data(k)
。
如果您Data
从某个外部来源获得了一个值,并且需要将其作为类型化的指针传递给API,那么最简单,最安全的选择就是将它变成一个数组,然后再说Array(someData)
。
例如:
let args = call.arguments as! NSDictionary
let server_pk = (args["server_pk"] as! FlutterStandardTypedData).data
let server_sk = (args["server_sk"] as! FlutterStandardTypedData).data
let client_pk = (args["client_pk"] as! FlutterStandardTypedData).data
var rx = [UInt8](repeating: 0, count: Flutter_sodium.crypto_kx_sessionkeybytes())
var tx = [UInt8](repeating: 0, count: Flutter_sodium.crypto_kx_sessionkeybytes())
Flutter_sodium.crypto_kx_server_session_keys(
&rx, &tx, Array(server_pk), Array(server_sk), Array(client_pk)
)
您 可能 可以使用withUnsafeBytes
并调用bindMemory
基础指针,但是我不建议这样做,因为它会更改基础内存的类型,这可能会因为您要切换出该事实而潜在地影响共享该内存的任何其他Swift代码的健全性下面的类型。