介紹
在網(wǎng)上看到一篇文章: 用 Kotlin Native 寫 Jni畔濒,以后寫 Android 基本上要沒有別的語言什么事兒了的節(jié)奏扬绪,卓的JNI環(huán)境好像是自動配置别凹,這里來介紹一下非安卓環(huán)境的kotlin-native JNI開發(fā)的環(huán)境配置芍锚。
環(huán)境配置
- 準(zhǔn)備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項目炫惩,創(chuàng)建gradle的腳本文件和def文件
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
-
執(zhí)行cinteropJniKotlin-jni
-
生成的包僻弹,現(xiàn)在可以帶著Clion的提示進(jìn)行開發(fā)了
開始jni開發(fā)
java調(diào)用jni
- 在jni.kt寫入如下代碼,@CName表示到處的C函數(shù)的名字他嚷,為了jni能找到對應(yīng)的函數(shù)蹋绽,格式是
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
-
接下來執(zhí)行之前的java代碼KotlinDLLDemo.class
jni中調(diào)用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靜態(tài)方法
val methodId = jniEnvVal.GetMethodID!!.invoke(env, jclass, "sayHi".cstr.ptr, "()Ljava/lang/String;".cstr.ptr)
print("In Kotlin Native: ")
// 調(diào)用sayHi方法
val jStrFromJava = jniEnvVal.CallObjectMethodA!!.invoke(env, thiz, methodId, null) as jstring
// 將jstring轉(zhuǎn)換為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筋蓖,然后執(zhí)行java代碼