美文网首页kotlin native 入门&进阶
kotlin-native05 进行JNI开发

kotlin-native05 进行JNI开发

作者: hohov | 来源:发表于2019-08-11 18:50 被阅读0次

    介绍

    在网上看到一篇文章: 用 Kotlin Native 写 Jni,以后写 Android 基本上要没有别的语言什么事儿了的节奏,卓的JNI环境好像是自动配置,这里来介绍一下非安卓环境的kotlin-native JNI开发的环境配置。

    环境配置

    • 准备java类
    package cn.hohov.demo;
    
    public class KotlinDLLDemo {
    
        static {
            System.load("D:\\Workplace\\Clion\\kotlin-jni\\build\\bin\\Dll\\jniDllReleaseShared\\jniDll.dll");
        }
    
        public native String nativeString();
    
    
        public String sayHi() {
            return "str from java";
        }
    
        public static void main(String[] args) {
            KotlinDLLDemo demo = new KotlinDLLDemo();
            System.out.println(demo.nativeString());
        }
    }
    
    • 新建空的kotlin-native项目,创建gradle的脚本文件和def文件


      build.gradle.kts
    plugins {
        kotlin("multiplatform") version "1.3.41"
    }
    
    repositories {
        mavenCentral()
    }
    
    kotlin {
        mingwX64("Dll") {
            compilations.getByName("main") {
                val jni by cinterops.creating {
                    // def文件路径
                    defFile(project.file("def/jni.def"))
    
                    // def生成的kotin库包名
                    packageName("jni")
    
                    // jni所需头文件的路径
                    includeDirs("C:\\Program Files\\Java\\jdk1.8.0_191\\include", 
                                "C:\\Program Files\\Java\\jdk1.8.0_191\\include\\win32")
                }
            }
            binaries {
                sharedLib("jniDll") {
                    baseName = "jniDll"
                }
            }
        }
    }
    
    headers = jni.h
    
    项目结构
    • 执行cinteropJniKotlin-jni


      gradle interop
    • 生成的包,现在可以带着Clion的提示进行开发了


      jni lib

    开始jni开发

    java调用jni

    • 在jni.kt写入如下代码,@CName表示到处的C函数的名字,为了jni能找到对应的函数,格式是Java_包名_类名_方法名
    package cn.hohov.jni
    
    import jni.JNIEnvVar
    import jni.jobject
    import jni.jstring
    import kotlinx.cinterop.*
    
    @CName("Java_cn_hohov_demo_KotlinDLLDemo_nativeString")
    fun stringFromJNI(env: CPointer<JNIEnvVar>, thiz: jobject): jstring {
        memScoped {
            return env.pointed.pointed!!.NewStringUTF!!.invoke(env, "This is from Kotlin Native!!".cstr.ptr)!!
        }
    }
    
    • 编译项目,生成dll


      jniDll.dll
    • 接下来执行之前的java代码KotlinDLLDemo.class


      执行结果

    jni中调用java方法

    • 修改jni.kt的代码
    package cn.hohov.jni
    
    import jni.JNIEnvVar
    import jni.jobject
    import jni.jstring
    import kotlinx.cinterop.*
    
    @CName("Java_cn_hohov_demo_KotlinDLLDemo_nativeString")
    fun stringFromJNI(env: CPointer<JNIEnvVar>, thiz: jobject): jstring {
        memScoped {
            val jniEnvVal = env.pointed.pointed!!
            val jclass = jniEnvVal.GetObjectClass!!.invoke(env, thiz)
            // 获取sayHi静态方法
            val methodId = jniEnvVal.GetMethodID!!.invoke(env, jclass, "sayHi".cstr.ptr, "()Ljava/lang/String;".cstr.ptr)
            print("In Kotlin Native: ")
            // 调用sayHi方法
            val jStrFromJava = jniEnvVal.CallObjectMethodA!!.invoke(env, thiz, methodId, null) as jstring
            // 将jstring转换为kotlin中的string
            val stringFromJava = jniEnvVal.GetStringChars!!.invoke(env, jStrFromJava, null)!!.toKString()
            println(stringFromJava)
            return env.pointed.pointed!!.NewStringUTF!!.invoke(env, "This is from Kotlin Native!!".cstr.ptr)!!
        }
    }
    
    • build,然后执行java代码


      执行结果

    参考链接

    相关文章

      网友评论

        本文标题:kotlin-native05 进行JNI开发

        本文链接:https://www.haomeiwen.com/subject/yqusjctx.html