Kotlin开发jni程序 二.C调用java/kotlin方法和属性

本文详细介绍了在C语言中调用Kotlin静态和实例方法的步骤,包括如何通过JNI找到类、方法ID,调用方法及释放资源。涵盖了调用静态方法、实例方法和属性的具体实现。

首先我们声明kotlin的几个方法和属性,如下

package com.example.firstjni

import android.util.Log

object NDKUtil{
    val name = "djfklsd"
    external fun updateArray(array: IntArray)
    external fun updateArrayByPointer(array: IntArray)
    external fun callStaticMethod(i: Int)
    external fun callStaticMethod(i: Long)
    external fun callInstanceMethod(i: Int)
    external fun callInstanceMethod(s: String,i: Long)

    @JvmStatic
    fun callStaticJavaMethod(s: String?,i: Int){
        val len = s!!.length
        Log.i("native","c调用了java静态方法  $s  $i")

    }

    fun callJavaMethod(s: String,i: Int){
        Log.i("native","c调用了java方法  $s  $i")
    }
}

调用java或kotlin方法和属性基本步骤分4步
1.找到类,实例方法和属性要创建对象
2.找到方法或属性id
3.调用方法
4.释放资源

1.C调用kotlin静态方法
首先说一点,kotlin的object类和compaion object中,属性声明都是静态的,方法并不是静态,必须通过@JvmStatic注解,
方法才会声明为静态
在这里插入图片描述
可以看到kotlin反编译出的代码,只有@JvmStatic声明的方法才真正是静态方法,然后就可以在C中调用静态的方法

//1.首先要在C中获取jclass对象,也就是找到方法所在的类,通过完整  包名+类名
jclass java_first = env->FindClass("com/example/firstjni/NDKUtil");

/**2.找到该方法的方法ID
*参数一:jclass
*参数二:方法名
*参数三:方法签名
*方法签名,网上有详细说明,如果不想查,可以使用javap -s指令查询
*/
 jmethodID static_method_id = env->GetStaticMethodID(java_first, "callStaticJavaMethod",
                                                            "(Ljava/lang/String;I)V");

/**3.调用静态方法
*参数一:jclass
*参数二:方法ID
*参数三:参数三是可变长参数,也就是该方法声明时候对应的参数列表,相当于调用方法时的传参
*这个方法声明的是(s: String, i: Int)
*/
env->CallStaticVoidMethod(java_first, static_method_id, NULL, 2);

//4.删除掉本地引用
env->DeleteLocalRef(java_first);

javap命令查询
在这里插入图片描述
对于kotlin来说,先通过AS下面的Termial进入build\tmp\kotlin-classes\debug目录 调用javap -s 包名+类名,就会为你显示该类所有的方法签名,就是
descriptor:后面的部分 ,例如:()Ljava/lang/String;

2.调用实例方法
实例方法调用步骤类似,不过实例方法需要对象调用,而不能是直接通过类调用,需要先通过构造器创建对象

//1.找到类
jclass java_first = env->FindClass("com/example/firstjni/NDKUtil");```

//2.找到构造器方法,这个相当于查找无参构造器
jmethodID construct = env->GetMethodID(java_first, "<init>", "()V");

//3.创建对象
jobject NDKObj = env->NewObject(java_first, construct);

//4.再回到和静态调用差不多的步骤,找到目标方法
jmethodID jmethodID1 = env->GetMethodID(java_first, "callJavaMethod", "(Ljava/lang/String;I)V");

//5.通过对象调用方法,这个方法参数是(s: String, i: Int)
jstring message = env->NewStringUTF("调用成功了");
env->CallVoidMethod(NDKObj, jmethodID1, message, 1);

//6.释放资源
env->DeleteLocalRef(message);
env->DeleteLocalRef(NDKObj);

3.调用属性

//调用静态属性

//1.找类
jclass java_first = env->FindClass("com/example/firstjni/NDKUtil");

//2.找属性ID
jfieldID name_id = env->GetStaticFieldID(java_first, "name", "Ljava/lang/String;");

//3.获取属性,string类型是通过GetStaticObjectField,其他的属性都有对应的方法,比如对于Int 就是GetStaticIntField
jstring name_obj = (jstring) env->GetStaticObjectField(java_first, name_id);

//至于实例属性,和调用实例方法步骤差不多,这里不多赘述

NOTE:查找方法和属性ID的时候,方法签名有多个参数,要用;隔开,如果只有一个参数,结尾也要用;

分析报错Abnormal build process termination: D:\admin\OpenJDK\jdk-21\bin\java.exe -Xmx700m -Djava.awt.headless=true "-Djna.boot.library.path=C:\Program Files\JetBrains\IntelliJ IDEA 2024.3.6/lib/jna/amd64" -Djna.nosys=true -Djna.noclasspath=true --add-opens jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-opens jdk.compiler/com.sun.tools.javac.jvm=ALL-UNNAMED -Dpreload.project.path=E:/omada_ai_assistant -Dpreload.config.path=C:/Users/admin/AppData/Roaming/JetBrains/IntelliJIdea2024.3/options -Dexternal.project.config=C:\Users\admin\AppData\Local\JetBrains\IntelliJIdea2024.3\projects\omada_ai_assistant.d7fc0b20\external_build_system -Dcompile.parallel=true -Drebuild.on.dependency.change=true -Didea.IntToIntBtree.page.size=32768 -Djdt.compiler.useSingleThread=true -Daether.connector.resumeDownloads=false -Dio.netty.initialSeedUniquifier=-6726313177566477740 -Djps.use.dependency.graph=true -Dfile.encoding=UTF-8 -Duser.language=zh -Duser.country=CN -Didea.paths.selector=IntelliJIdea2024.3 "-Didea.home.path=C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6" -Didea.config.path=C:/Users/admin/AppData/Roaming/JetBrains/IntelliJIdea2024.3 -Didea.plugins.path=C:/Users/admin/AppData/Roaming/JetBrains/IntelliJIdea2024.3/plugins -Djps.log.dir=C:/Users/admin/AppData/Local/JetBrains/IntelliJIdea2024.3/log/build-log "-Djps.fallback.jdk.home=C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/jbr" -Djps.fallback.jdk.version=21.0.6 -Dio.netty.noUnsafe=true -Djava.io.tmpdir=C:/Users/admin/AppData/Local/JetBrains/IntelliJIdea2024.3/compile-server/omada_ai_assistant_48840d96/_temp_ -Djps.backward.ref.index.builder=true -Djps.backward.ref.index.builder.fs.case.sensitive=false -Dcompilation.charts=false "-Djps.kotlin.home=C:\Program Files\JetBrains\IntelliJ IDEA 2024.3.6\plugins\Kotlin\kotlinc" -Dkotlin.incremental.compilation=true -Dkotlin.jps.dumb.mode=true -Dkotlin.jps.enable.lookups.in.dumb.mode=true -Dkotlin.incremental.compilation.js=true -Dkotlin.daemon.enabled -Dkotlin.daemon.client.alive.path=C:\Users\admin\AppData\Local\Temp\kotlin-idea-5726179449608968503-is-running -Dide.propagate.context=false -classpath "C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/java/lib/jps-launcher.jar" org.jetbrains.jps.cmdline.Launcher "C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/java/lib/jps-builders.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/java/lib/jps-builders-6.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/java/lib/jps-javac-extension.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/lib/util-8.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/lib/util_rt.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/lib/platform-loader.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/lib/annotations.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/lib/trove.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/java/lib/jetbrains.kotlinx.metadata.jvm.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/lib/protobuf.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/java/lib/rt/netty-jps.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/lib/jps-model.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/java/lib/javac2.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/lib/forms_rt.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/lib/util.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/lib/lib-client.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/java/lib/aether-dependency-resolver.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/java/lib/maven-resolver-connector-basic.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/java/lib/maven-resolver-transport-file.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/java/lib/maven-resolver-transport-http.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/lib/idea_rt.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/JavaEE/lib/jasper-v2-rt.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/Kotlin/lib/jps/kotlin-jps-plugin.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/lib/util-8.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/java/lib/jps/java-compiler-charts-jps.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/javaFX/lib/javaFX-jps.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/javaFX/lib/javaFX-common.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/eclipse/lib/eclipse-jps.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/eclipse/lib/eclipse-common.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/JavaEE/lib/jps/javaee-jps.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/platform-langInjection/lib/java-langInjection-jps.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/Groovy/lib/groovy-jps.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/Groovy/lib/groovy-constants-rt.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/maven/lib/maven-jps.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/gradle-java/lib/gradle-jps.jar;C:/Program Files/JetBrains/IntelliJ IDEA 2024.3.6/plugins/JPA/lib/jps/javaee-jpa-jps.jar" org.jetbrains.jps.cmdline.BuildMain 127.0.0.1 55401 1e798a88-0aaf-4836-8f44-e98acedbe947 C:/Users/admin/AppData/Local/JetBrains/IntelliJIdea2024.3/compile-server # # A fatal error has been detected by the Java Runtime Environment: # # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00007ffc55fa8cb6, pid=7008, tid=41504 # # JRE version: (21.0+35) (build ) # Java VM: OpenJDK 64-Bit Server VM (21+35-2513, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, windows-amd64) # Problematic frame: # V [jvm.dll+0x308cb6]# # No core dump will be written. Minidumps are not enabled by default on client versions of Windows # # An error report file with more information is saved as: # C:\Users\admin\AppData\Local\JetBrains\IntelliJIdea2024.3\compile-server\hs_err_pid7008.log # #
最新发布
12-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值