Not sure how KN is transparently calling `Java_org...
# kotlin-native
g
Not sure how KN is transparently calling
Java_org_jetbrains_skija_Canvas__1nDrawPicture
without (what looks like) passing any
JNIEnv
🤔
a
🙏 2
g
Are these auto-generated (or at least mostly), Alexander? The calls seem to be mostly identical except for swapping
JNIEnv*
pointer for
kref __Kinstance
o
autogenerated only for simple cases, for harder cases JS and Native are the same and JVM are different
👌 1
g
technically Skiko is an approach to multiplatform native interop for all major Kotlin targets
I am hoping for a not-so-distant future in which Skiko is used as the rendering backend for Compose on iOS. Then you can use a single Kotlin codebase and UI framework to build experiences across all targets -- even the browser! Unfortunately, it seems the KN part of Skiko is fairly young, was only MacOS supported until recently, now there is at least a Linux OpenGL renderer. Though it a stub for now
What Mono and .NET did for Skia was to wrap the C++ in a C ABI and then call this: • https://github.com/mono/skia/blob/xamarin-mobile-bindings/include/c/sk_types.h It is used here: • https://github.com/mono/SkiaSharp
I have considered to build the
xamarin-mobile-bindings
branch which has the C ABI that Microsoft uses, and then generate Kotlin Native interop types from it and experiment with that. Would maybe save a lot of effort.
o
API shape would look uglier then. We considered such approach
g
I figured as such, Jetbrains has a lot of talented programmers, resources, and money. I thought they must have considered it and instead decide to maintain their own and build by hand over a longer time period for more control.
s
@olonho https://github.com/Kotlin/KEEP/pull/279 As I discussed here, we can write the library in Kotlin-Native, and use JNI to use the compiled kotlin native library directly. Which has several ways. The way I use in my own project is to use ksp to generate classes that every method is export and use it on kotlin JVM, and create other sets of native platforms which are going to be used by JNI, using JNI in kotlin native is simple, cinterop support it. For link the native method to JVM, you can simply use @CName("Java_org_jetbrains_skiko_blablabla") or through JNI method
Copy code
memScoped {
            val mP = alloc<JNINativeMethod> {
                name = methodName.cstr.ptr
                signature = descriptor.cstr.ptr
                fnPtr = m // native function pointer
            }
            env.pointed.pointed!!.RegisterNatives!!(env, findClass(className), mP.ptr, 1)
        }
The native function pointer can used as
Copy code
staticCFunction<CPointer<JNIEnvVar>, jobject, jdouble> { env, t,  -> 
// same as fun yourMethod(env: CPointer<JNIEnvVar>, obj: jobject) : jdouble
// jdouble is a primitive, cinterop will make typealias points to kotlin.Double, the result can't be null
 }
use kotlin ir to generating these are fast and simple, as long as the code is well organized
g
The way I use in my own project is to use
ksp
to generate classes that every method is export and use it on kotlin JVM, and create other sets of native platforms which are going to be used by JNI, using JNI in kotlin native is simple,
cinterop
support it.
For link the native method to JVM, you can simply use
@CName("Java_org_jetbrains_skiko_blablabla")
or through JNI method
This is a really clever approach @smallshen!
Copy code
memScoped {
            val mP = alloc<JNINativeMethod> {
                name = methodName.cstr.ptr
                signature = descriptor.cstr.ptr
                fnPtr = m // native function pointer
            }
            env.pointed.pointed!!.RegisterNatives!!(env, findClass(className), mP.ptr, 1)
        }
Do I understand right, that this snippet of code says? • Allocate a value,
mP
, of type
JNINativeMethod
where: ◦ The
name
= the Kotlin Native method's name, as a
cstr*
◦ The
signature
= the Kotlin Native method's descriptor, as a
cstr*
◦ The
fnPtr
itself =
m
, which points to the Kotlin Native function • Then, register a new JNI method in the
JNIEnv
natives from this KN definition
Do you have a very basic project on Github which shows using this for just a few functions as a demo?
s
@Gavin Ray this is the actual code, just replace the values, I'll make a simple demo
🙌 1