Sergey Y.
05/24/2023, 9:09 AMSergey Y.
05/24/2023, 9:17 AMOleg Yukhnevich
05/24/2023, 9:26 AMjvm
flavour is highly undocumented and not usable in current state externally, though it powers K/N compiler 🙂
Regarding examples usage of native libraries from K/N and K/JVM here what I know:
• realm-kotlin - https://github.com/realm/realm-kotlin/tree/main/packages/cinterop
• zipline - https://github.com/cashapp/zipline/tree/trunk/zipline
also I have some WIP prototype of multiplatform cinterop
here - https://github.com/whyoleg/ffi-kotlin
though it’s far from production ready nowSergey Y.
05/24/2023, 9:30 AMSergey Y.
05/24/2023, 10:32 AMOleg Yukhnevich
05/24/2023, 10:40 AMkotlinx.cinterop
APISergey Y.
05/24/2023, 10:47 AMOleg Yukhnevich
05/24/2023, 10:50 AMSergey Y.
05/24/2023, 11:42 AM// ImageProcessing.kt file
@JniExport
fun crunchPixels(image: ByteArray): ByteArray {
/*impl*/
return newImage
}
// Android module/source set
object ImageProcessing {
external fun crunchPixels(image: ByteArray): ByteArray
}
This is an overly simplified sample. Ideally, I want to minimize the interaction with JNI/NDK machinery, move it behind the scene. The goal is to blur the line between JVM code and native code interaction. The approach is similar to writing code inside the common source set with Multiplatform. As long as we stay within the boundaries of the standard library and avoid passing platform-specific elements to and from native code, the native function calls are indistinguishable from any other function calls.
Ideally, if we have an immutable data class in the common source set, containing only primitive data types, we should be able to pass and receive it without any JNI friction, just like in regular Kotlin code.
// Common source set
@JniShared // IDK, or Shared
data class DataHolder(val foo: Int, val bar: String)
// JVM source set
object NativeHost {
external fun bazz(data: DataHolder): DataHolder
}
// Native source set
// NativeHost.kt file
@JniExport
fun bazz(data: DataHolder): DataHolder {
val newDataHolder: DataHolder = process(data)
return newDataHolder
}
Here, we interact with the given data class instance like in regular code, without the need for JNIEnvVar operations to extract the values and return it back.
Although I may not have extensive experience in native development, I have attempted to describe a solution that could potentially simplify my workflow when working with native code. While it may be challenging or even impossible to achieve everything I mentioned, I believe that the ideas presented could greatly enhance my experience and streamline the process of integrating native components. 😄Landry Norris
05/24/2023, 1:36 PM