Hello! Yet another question. I'm trying to suppres...
# kotlin-native
d
Hello! Yet another question. I'm trying to suppress the "kotlinx.cinterop.staticCFunction must take an unbound, non-capturing function or lambda" error. I naively tried to use
@Suppress("errors")
but that doesn't work. I understand the risks, and let just say that "I know what I am doing" (hm hm...).
Copy code
package kextract.runtime

import kotlinx.cinterop.ExperimentalForeignApi

@OptIn(ExperimentalForeignApi::class)
@Suppress("errors")
actual fun <R> staticCFunction(function: () -> Unit): CPointer<() -> R> {
    return CPointer.Opaque(kotlinx.cinterop.staticCFunction(function).rawValue.toLong().toMemorySize())
    //                                      ^^^^^ kotlinx.cinterop.staticCFunction must take an unbound, non-capturing function or lambda
}
Any hints as to how I should proceed? (Ideally, I would like that the Kotlin compiler applies the same check to users of my custom
staticCFunction
but I guess that's another question for another day.)
d
Thanks @Youssef Shoaib [MOD]! It seems I hit a roadblock... 😭
a
iiuc it's not a limitation of the Kotlin compiler, C just doesn't have 'closures'. You can pass a function pointer (i.e. a static function/lambda), but that won't include the captured variables.
what are you trying to achieve? What do you need to do that requires passing a lambda in?
y
This is likely a bad idea, but I wonder if it'd work if you defined it exactly like the compiler does
In addition, I wonder if you can actually have an
external
implementation. You'd then be able to get what you want without any of the static checks. It seems like it's an intrinsic that the compiler deals with, though...
d
@Adam S yeah, I understand the non-capturing aspect and it's not a problem. My problem is that I can't wrap those calls in my own API.
@Youssef Shoaib [MOD] thanks, I will look into that. (I already use
@CCall
for my generated bindings, thanks to Oleg and his
kotlin-interop-playground
!)
It would be great if the low-level API used by
cinterop
would be more open and documented. 😊 (Or have multiplatform
cinterop
... 😁)
a
I understand the non-capturing aspect and it's not a problem
could you say more? (I'm asking because I'd like to learn more about the C side of K/N development)
could you express the function you need in C? If so you could define it in the .def file, so cinterop will generate it.
d
@Adam S I don't use
cinterop
. I generate bindings that directly bind to C via
external
functions. (And it's a bit of a mess! 😊) I recommend you to look at Oleg's Kotlin Interop Playground . It will give you a good overview of the ways to bind to C. He does it two ways: with
cinterop
in
c-interop/native-cinterop
and without, in
c-inherop/native-raw
.
a
I'm not familiar with using external to bind with C, but it sounds like the result would be the same. You'd effectively be implementing your own
staticCFunction
.
👍 1
l
Can't you just create a native function (in the native block in the def file) that takes the pointer and then calls it?
d
@loke I am not sure I understand what you suggested. I gather that I need to implement a Kotlin function (let's call it
toNativeFunctionPointer
) that takes a Kotlin function (let's call it
f
) and returns a native function pointer. That native function pointer would convert parameters from Kotlin to native, then calls
f
, and finally converts the return value from native to Kotlin. The conversions are easy and done. The hard part is the "calling the Kotlin function".