Kotlin 对象到 CPointer

Kotlin Object to CPointer

我正在尝试将 Kotlin 对象传递给 C 库,后者会将该对象传递给回调函数。这个函数是用 Kotlin 编写的,因此我可以使用这个对象并使用它。但是我找不到将 Kotlin 对象转换为 CPointer 的方法。我发现的唯一可能是我需要的东西是 fun createKotlinObjectHolder(any: Any?): NativePtrfun <reified T : Any> unwrapKotlinObjectHolder(holder: Any?): T。但即使我使用刚刚创建的 NativePtr 将其传递给解包函数,它也会失败并显示错误消息 unrecognized selector sent to instance 0xXYZ。我做错了什么或者那些不是我应该使用的功能?

带有 libcURL 的示例代码:

fun writeCallback(ptr: CPointer<ByteVar>, ignored: ULong, size: ULong, userData: COpaquePointer?): ULong {
    if (userData != null) {
        unwrapKotlinObjectHolder<StringBuilder>(userData.rawValue).append("Hello")
    }
    return size
}

fun main() {
    ...
    val curl = curl_easy_init()
    ...
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, staticCFunction(::writeCallback))

    val stringBuilder = StringBuilder()
    val nativePtr = createKotlinObjectHolder(stringBuilder)
    val cPtr = interpretCPointer<CPointed>(nativePtr)
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, cPtr)
    ...
}

代码在 macOS 上编译。

有一个 StableRef class,在这种情况下应该使用它来包装 Kotlin 实例。此代码应该可以正常工作:

fun writeCallback(ptr: CPointer<ByteVar>, ignored: ULong, size: ULong, userData: COpaquePointer?): ULong {
    if (userData != null) {
        userData.asStableRef<StringBuilder>().get().append("Hello")
    }
    return size
}

fun main() {
    /* get a curl handle */
    val curl = curl_easy_init();
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, staticCFunction(::writeCallback))
    val stringBuilder = StringBuilder()
    val stableRef = StableRef.create(stringBuilder)
    val cPtr = stableRef.asCPointer()
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, cPtr)

    curl_easy_perform(curl)

    curl_easy_cleanup(curl)
    stableRef.dispose()
}

有关其他信息,请参阅文档的 this 页。