Wireless4024
Wireless4024

Reputation: 71

How can I call JNIEnv function from Kotlin/Native

jni.h provide this

struct JNINativeInterface_ {
    ...
    jint (JNICALL *GetVersion)(JNIEnv *env);
    ...
}

to call it in C can be written as

void test(JNIEnv *env){
    // C
    jint version = (*env)->GetVersion(env);

    // C++
    // jint version = env->GetVersion(); 
}

and then how can I do it in kotlin?

fun test(env: CPointer<JNIEnvVar>){
    val version = // how?
}

After searching answer in google there are few example for Kotlin/Native with JNI but they're just basic example please help.

Thanks in advance.

Upvotes: 2

Views: 302

Answers (2)

Tom Rutchik
Tom Rutchik

Reputation: 1692

Wireless4024's answer is correct, but I struggled to get it too work! The problem was that JNIEnvVar was undefined and it wasn't clear what I need to do to get that to resolve. I'll just augment Wireless4024's answer with what you need to do to be able to reference JNI structures in kotlin/native functions.

You need to add a dependency to the kotlin "std-jdk8". Here's an gradle kts script code snippet for doing that

kotlin {
    ...
   sourceSets {
       nativeMain.dependencies {
            implementation (kotlin("std-jdk8))
   }
    ...
}

An easy mistake since your planning on making native code, so you might not think the you need the kotlin std-jdk8 dependency.

Upvotes: 0

Wireless4024
Wireless4024

Reputation: 71

Thanks to Michael.

Long answer is

fun test(env: CPointer<JNIEnvVar>){
    // getting "JNINativeInterface_" reference from CPointer<JNIEnvVar> by 
    val jni:JNINativeInterface_ = env.pointed.pointed!!

    // get function reference from JNINativeInterface_
    // IntelliJ can help to find existing methods
    val func = jni.GetVersion!! 

    // call a function
    var version = func.invoke(env)

    // above expression can be simplify as
    version = env.pointed.pointed!!.GetVersion!!(env)!!
}

hope this can help somebody to understand Kotlin/Native 🙂.

Upvotes: 1

Related Questions