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

KMM iOS侧使用c_interop集成SQLCipher的指针代码转换问题

问题根因

  • 崩溃直接原因是sqlite3_open的第二个参数传了空指针:C接口的sqlite3_open要求第二个参数是sqlite3 **类型,用来存放返回的数据库实例指针,你传入null相当于让系统往0地址写数据,直接触发EXC_BAD_ACCESS崩溃
  • 类型不匹配问题是你混淆了两层指针:sqlite3_open接收的是二级指针(指向sqlite3指针的指针),而sqlite3_key要求的第一个参数是一级指针(sqlite3实例本身的指针),官方示例用同一个变量是因为C里&db取的是二级指针,存好后db本身就是一级指针
  • 字符串传参报错是因为Kotlin字符串不能直接传给C接口,需要先转为C的UTF-8字符串指针

正确实现代码

import kotlinx.cinterop.*
import platform.Foundation.NSLog
// 这里替换为你cinterop生成的sqlcipher包名
import cnames.structs.sqlite3

fun openEncryptedDatabase(databasePath: String, password: String) = memScoped {
    // 分配二级指针空间,用来接收sqlite3_open返回的实例
    val dbPtr = alloc<CPointerVar<sqlite3>>()
    // 打开数据库
    val openCode = sqlite3_open(databasePath, dbPtr.ptr)
    if (openCode == SQLITE_OK) {
        NSLog("Successfully opened connection to database")
        // 取出一级指针,用来给sqlite3_key传参
        val db = dbPtr.value ?: error("Database pointer is null after open success")
        // 把Kotlin字符串转为C的UTF8指针
        password.cstr.usePinned { pinnedPwd ->
            val keyCode = sqlite3_key(
                db = db,
                pKey = pinnedPwd.addressOf(0),
                nKey = password.length.toInt()
            )
            // 这里可以加keyCode的判断逻辑
            if (keyCode == SQLITE_OK) {
                NSLog("SQLCipher key set success")
            }
        }
        // 注意用完数据库要调用sqlite3_close(db)释放资源
    } else {
        NSLog("Open database failed, code: $openCode")
    }
}

关键逻辑说明

  • memScoped块:用来管理C指针的生命周期,块内分配的native内存会在块结束后自动释放,避免内存泄漏
  • alloc<CPointerVar<sqlite3>>():分配一个二级指针对象,对应C代码里sqlite3 *db;的&db取值
  • dbPtr.value:取出二级指针指向的一级sqlite3实例指针,对应C代码里直接用的db变量,刚好匹配sqlite3_key的第一个参数类型
  • password.cstr.usePinned:把Kotlin字符串转为C兼容的UTF-8字节数组,固定内存地址后拿到指针传给sqlite3_key,自动处理类型转换问题
  • 如果编译提示找不到SQLITE_OK常量,可手动定义const val SQLITE_OK = 0,这是sqlite标准的成功返回码

内容的提问来源于stack exchange,提问作者Ayohaych

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 16:15:02