Kotlin Multiplatform iOS调用CCCrypt时CValuesRef取值异常问题
问题根源
- 你读取
numBytesEncrypted值时创建了新的MemScope(),和CCCrypt执行时所在的memScoped生命周期完全隔离,拿到的是野指针对应的无效值,因此始终返回0。 - 用
cValue传递out参数的语法本身没有问题,但读取值的方式错误,更推荐直接在当前内存作用域分配变量,写法更直观。
修正后的完整代码
private fun process(operation: CCOperation, key: ByteArray, initVector: ByteArray, data: ByteArray): ByteArray = memScoped { bzero(key.refTo(0), key.size.convert()) val dataLength = data.size val buffSize = (dataLength + kCCBlockSizeAES128.toInt()).convert<size_t>() val buff = platform.posix.malloc(buffSize) // 直接在当前memScoped作用域分配size_t类型变量 val numBytesEncrypted = alloc<ULongVarOf<size_t>>() val status = CCCrypt( operation, kCCAlgorithmAES128, kCCOptionPKCS7Padding, key.refTo(0), kCCKeySizeAES256.convert(), initVector.refTo(0), data.refTo(0), data.size.convert(), buff, buffSize, numBytesEncrypted.ptr // 直接传递变量指针即可 ) if (status == kCCSuccess) { // 读取实际加密/解密长度,生成NSData后转ByteArray,手动释放malloc内存 val result = NSData.dataWithBytes(buff, numBytesEncrypted.pointed.value) .toByteArray() free(buff) return result } free(buff) return byteArrayOfUnsigned(0) } fun NSData.toByteArray(): ByteArray = ByteArray(this@toByteArray.length.toInt()).apply { usePinned { memcpy(it.addressOf(0), this@toByteArray.bytes, this@toByteArray.length) } }
若坚持使用cValue的修正方案
如果你不想修改变量声明方式,只需把读取值时的MemScope()替换为当前memScoped块的作用域即可:
// 变量声明不变 val numBytesEncrypted = cValue<ULongVarOf<size_t>>() // 读取时用当前memScoped的receiver,不要新建MemScope numBytesEncrypted.getPointer(this).pointed.value
修改后你的单元测试可正常通过,能够正确获取加密解密后的数据长度。
内容的提问来源于stack exchange,提问作者MrAsterisco
相关产品推荐
相关产品推荐

