Kotlin 对象到 CPointer
Kotlin Object to CPointer
我正在尝试将 Kotlin 对象传递给 C 库,后者会将该对象传递给回调函数。这个函数是用 Kotlin 编写的,因此我可以使用这个对象并使用它。但是我找不到将 Kotlin 对象转换为 CPointer 的方法。我发现的唯一可能是我需要的东西是 fun createKotlinObjectHolder(any: Any?): NativePtr
和 fun <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 页。
我正在尝试将 Kotlin 对象传递给 C 库,后者会将该对象传递给回调函数。这个函数是用 Kotlin 编写的,因此我可以使用这个对象并使用它。但是我找不到将 Kotlin 对象转换为 CPointer 的方法。我发现的唯一可能是我需要的东西是 fun createKotlinObjectHolder(any: Any?): NativePtr
和 fun <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 页。