【问题标题】:How to create void* pointer for kotlin native如何为 kotlin native 创建 void* 指针
【发布时间】:2026-01-10 02:25:01
【问题描述】:

我正在尝试使用本机库将现有的 c 代码转换为 kotlin。 到目前为止,我成功地开始了,但被用于访问结构或对象的指针所困扰。 像这样在c中:

void *ptr;
foo(&ptr); //init is done inside
bar(&ptr); //ptr is reused

但是如何将这些指针保存在 kotlin 中? 这样的尝试:

var avar = CPointerVarOf<COpaquePointer>(NativePtr.NULL)
var bvar: CPointerVarOf<CPointer<*>> = null

结果

Native interop types constructors must not be called directly

我读到: kotlin inerop

感谢任何提示。

【问题讨论】:

    标签: c kotlin kotlin-native gattlib


    【解决方案1】:

    我找到了一个可行的解决方案。我犯了一个错误,并认为我的指针分配是错误的,所以我复制了 ide 认为正确的内容。导致分配如下:

    var avar:COpaquePointerVar = alloc()
    

    现在 Kotlin 本机可以正确分配所有内容。但是纯分配很少能解决问题所以这里是代码:

    /* C Code */
    void* adapter;
    int ret;
    
    ret = gattlib_adapter_open(NULL, &adapter);
    if (ret) {
        fprintf(stderr, "ERROR: Failed to open adapter.\n");
        return 1;
    }
    
    ret = gattlib_adapter_scan_enable(adapter, ble_discovered_device, 5, NULL /* user_data */);
    if (ret) {
        fprintf(stderr, "ERROR: Failed to scan.\n");
    }
    
    gattlib_adapter_scan_disable(adapter);
    
    puts("Scan completed");
    

    在我注意到我的错误之后,我再次阅读了我的所有代码并在 c 中创建了一个工作示例。我将代码部分地从 c 移动到 kotlin native。 所以 kotlin 版本经历了几个阶段,最终以:

    /* Kotlin with native interop */
    memScoped {
        var avar: COpaquePointerVar = alloc()
        var ret = gattlib_adapter_open(null, avar.ptr)
        print("Adapter opened\n")
        if (ret > 0) {
            print( "ERROR: Failed to open adapter.\n");
            return
        }
    
        print("start scan\n")
        gattlib_adapter_scan_enable(avar.value, staticCFunction { a, b, c, d ->
            kotlin.native.initRuntimeIfNeeded()
            print("found dev\n")
        }, 5, NULL /* user_data */);
    
        gattlib_adapter_scan_disable(avar.value)
    
        print("Scan completed\n");
    }
    

    我是一名学生,所以这可能不是最佳做法,请随时纠正我。我希望这个 sn-p 可以帮助任何刚开始使用 kotlin native 的人。

    【讨论】:

      【解决方案2】:

      @巴苏尔!不能直接实例化指针类型。尝试在堆上或memScoped {...} 块内分配它们,如下所示:

      val voidy:COpaquePointerVar = nativeHeap.alloc()
      fun a(ptr:CPointer<COpaquePointerVar>){
          println(ptr.pointed.value)
          ptr.pointed.value = NULL
      }
      fun b(ptr:CPointer<COpaquePointerVar>){
          println(ptr.pointed.value)
      }
      a(voidy.ptr)
      b(voidy.ptr)
      ...
      nativeHeap.free(voidy)
      

      【讨论】:

      • 是的,我花了大约 16 小时才意识到这一点,另外 3 小时才发现我在代码中的错误......
      • 我在您发布此内容时写了一个答案,如果我现在看到并意识到我的错误在哪里,我会觉得有点愚蠢,我可能会为初学者构建一个 kotlin 本机示例的集合,我可以使用您的代码吗链接或直接引用您的帖子?
      • 好吧,不用提就随意使用它,恕我直言,你的更好?。我唯一建议你的是更新你的答案:不需要像你一样明确指定类型,val avar:COpaquePointerVar = alloc() 之类的东西应该可以解决问题。
      最近更新 更多