You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin Multiplatform iOS调用CCCrypt时CValuesRef取值异常问题

问题根源

  1. 你读取numBytesEncrypted值时创建了新的MemScope(),和CCCrypt执行时所在的memScoped生命周期完全隔离,拿到的是野指针对应的无效值,因此始终返回0。
  2. 用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 12:18:01