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

Kotlin c-interop调用Avro C时输出参数始终为空的问题

Kotlin/Native 调用Avro C输出参数返回null问题解决方案

问题根因

你当前的问题出在C输出参数的传参方式不符合Kotlin/Native cinterop的规则:
avro_schema_from_json的后两个参数为输出参数,C侧要求传入avro_schema_t*、avro_schema_error_t*类型的指针,指向用于存储结果的内存地址。你使用的cValuesOf()仅会将变量当前的静态值(此处为null)封装为C指针传入,并没有传入Kotlin变量本身的内存地址,因此C函数写入的结果无法回写到Kotlin侧的avro_c_schema和error变量中,导致即使返回值为0,两个变量依然为null。

正确实现代码

import kotlinx.cinterop.*

// Avro C 结构体导入根据你的cinterop配置自行调整

fun parseAvroSchema() {
    val json = """
    {
      "type": "record",
      "name": "list",
      "fields": [
        { "name": "x", "type": "int" },
        { "name": "y", "type": "int" },
        { "name": "next", "type": ["null","list"]}
      ]
    }
    """.trimIndent()

    memScoped {
        // 分配用于承载输出结果的native内存变量
        val schemaPtr = alloc<avro_schema_tVar>()
        val errorPtr = alloc<avro_schema_error_tVar>()

        // 传入变量的内存地址到C函数
        val resultInt = avro_schema_from_json(json, json.length.toULong(), schemaPtr.ptr, errorPtr.ptr)

        if (resultInt == 0) {
            // 读取C函数写入的schema结果
            val avroSchema = schemaPtr.value
            // 此处执行schema后续逻辑,如需在memScoped外持有schema,需调用Avro C的引用计数递增接口
        } else {
            // 读取错误信息
            val parseError = errorPtr.value
            // 此处执行错误处理逻辑
        }
    }
}

注意事项

  • avro_schema_tVar、avro_schema_error_tVar是cinterop工具根据C的类型定义自动生成的可变指针变量类型,与你导入的Avro C头文件绑定
  • memScoped作用域会在代码块执行完成后自动释放内部分配的临时native内存,如果你需要在作用域外长期持有解析得到的schema对象,需调用Avro C提供的schema引用计数增加接口,避免内存被提前回收
  • 传递字符串到C函数时,若遇到编码问题可显式调用json.cstr获取C兼容的字符串指针传入

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 07:24:03