Hello, we are trying to call a C function in Kotli...
# multiplatform
p
Hello, we are trying to call a C function in Kotlin MultiPlatform. We are running into an issue in which the C library we use is returning data inside of a call back instead of just returning the data. How can we get this data from our C callback to our Kotlin runtime?
Copy code
fun storeProvision() = runBlocking {

            fun storeProvisionCB (
                callbackId: CallbackId,
                errorCode: ErrorCode,
                storeHandle: StoreHandle,
            ){
// DATA WE NEED  vvvvvvvvvvvvvv
                println("Callback ID: $callbackId")
                println("Error code: $errorCode")
                println("Store handle: $storeHandle")
// DATA WE NEED  ^^^^^^^^^^^^^

            }

            val callback = staticCFunction(::storeProvisionCB)

            val errorCode = askar_store_provision(
                "<sqlite://local.db>",
                null,
                null,
                null,
                0,
                callback,
                21
            )

            println("Askar Error Code: $errorCode")
l
I would create a suspend function and use suspendCoroutine. This is how callbacks can be converted to a more 'kotliny' style. Make sure to know how the memory is managed for the params, though. It's still C.
j
staticCFunction
can't capture any variables. So you'll likely need to use a
StableRef
reference to a global variable to write the callback state to to be able to access outside the callback afterwards. C callback functions usually provide a way to pass this user defined reference into the callback. Looks like it might be the
callbackId
in your case.
p
@Landry Norris Do you have a recommendation on how to have a
staticCFunction
use
suspendCoroutine
?
l
Like mentioned above, you'll need to pass the continuation using some opaque pointer (most C libraries with callbacks have this). You can get the pointer using StableRef. Once you have the continuation in your C callback, call continuation.resume with the result you want to pass (I'd copy important fields to a Kotlin data class instead of returning a C struct for memory safety reasons.
I would do this in a storeProvisions() suspending method, which just sets up and calls your askar_store_provisions method.
p
Thank you so much for the help @Jeff Lockhart @Landry Norris. Got it working thanks to you two.