JNI: 在Kotlin和C++之间通过JNI进行接口传递,两边参数定义映射
创始人
2024-12-27 07:08:32
0

在Kotlin和C++之间通过JNI进行接口传递时,需要注意两边参数定义的映射关系。JNI(Java Native Interface)为Java(Kotlin也适用)与本地语言(如C/C++)之间的交互提供了桥梁。在Kotlin中定义的外部函数和C++中的实现需要通过JNI签名相互对应。

Kotlin端

在Kotlin中,我们定义一个包含external方法的类。例如:

package com.example.native  class NativeLib {     external fun stringFromJNI(): String     external fun addNumbers(a: Int, b: Int): Int      companion object {         init {             System.loadLibrary("native-lib")         }     } } 

C++端

在C++中,我们需要定义与Kotlin中external方法对应的函数实现,并使用正确的JNI签名。每个参数类型在JNI中都有对应的类型签名。

常见JNI类型签名
Kotlin类型JNI签名C++类型
IntIjint
LongJjlong
BooleanZjboolean
ByteBjbyte
CharCjchar
ShortSjshort
FloatFjfloat
DoubleDjdouble
StringLjava/lang/String;jstring
Array[jarray
ObjectL…;jobject
示例:实现stringFromJNIaddNumbers
  1. 生成JNI头文件

    假设已经生成了Kotlin类对应的.class文件,可以使用javac生成头文件:

    javac -h . path/to/classes/com/example/native/NativeLib.class 

    生成的头文件com_example_native_NativeLib.h可能如下所示:

    /* DO NOT EDIT THIS FILE - it is machine generated */ #include  /* Header for class com_example_native_NativeLib */  #ifndef _Included_com_example_native_NativeLib #define _Included_com_example_native_NativeLib #ifdef __cplusplus extern "C" { #endif /*  * Class:     com_example_native_NativeLib  * Method:    stringFromJNI  * Signature: ()Ljava/lang/String;  */ JNIEXPORT jstring JNICALL Java_com_example_native_NativeLib_stringFromJNI   (JNIEnv *, jobject);  /*  * Class:     com_example_native_NativeLib  * Method:    addNumbers  * Signature: (II)I  */ JNIEXPORT jint JNICALL Java_com_example_native_NativeLib_addNumbers   (JNIEnv *, jobject, jint, jint);  #ifdef __cplusplus } #endif #endif 
  2. 实现C++方法

    创建对应的C++文件native-lib.cpp,并实现这些方法:

    #include  #include  #include "com_example_native_NativeLib.h"  JNIEXPORT jstring JNICALL Java_com_example_native_NativeLib_stringFromJNI(JNIEnv *env, jobject obj) {     std::string hello = "Hello from C++";     return env->NewStringUTF(hello.c_str()); }  JNIEXPORT jint JNICALL Java_com_example_native_NativeLib_addNumbers(JNIEnv *env, jobject obj, jint a, jint b) {     return a + b; } 

调用过程

  1. 加载本地库

    在Kotlin中,加载本地库并调用本地方法:

    package com.example.main  import com.example.native.NativeLib  fun main() {     val nativeLib = NativeLib()     val resultString = nativeLib.stringFromJNI()     val sum = nativeLib.addNumbers(3, 5)      println(resultString) // 输出: Hello from C++     println(sum) // 输出: 8 } 
  2. 确保本地库存在

    确保native-lib库文件存在并可以在运行时加载。通常在Android项目中,会把.so文件放在src/main/jniLibs/目录下。

注意

  • 方法签名必须完全匹配,包括参数类型和返回类型。
  • JNIEnv指针和jobject对象是每个本地方法的必需参数。
  • 字符串和数组等复杂类型需要使用JNI提供的函数进行转换和操作。

相关内容

热门资讯

解迷一下!微信边锋辅助挂件,约... 您好,微信边锋辅助挂件这款游戏可以开挂的,确实是有挂的,需要了解加去威信【136704302】很多玩...
曝光一下!江西中至小程序黑科技... 曝光一下!江西中至小程序黑科技,竹间穿有挂没,原来是有挂(哔哩哔哩)1、每一步都需要思考,不同水平的...
推荐一下!丰城呱呱辅助器,友乐... 推荐一下!丰城呱呱辅助器,友乐广西app下载安装,总是真的是有挂(哔哩哔哩)在进入丰城呱呱辅助器软件...
推荐一下!家乡大贰祈福有用吗,... 推荐一下!家乡大贰祈福有用吗,中至赣州黑科技辅助软件,切实真的是有挂(哔哩哔哩)1)家乡大贰祈福有用...
有挂一下!微玩体育辅助器,we... 有挂一下!微玩体育辅助器,wepkerplus辅助,本来真的有挂(哔哩哔哩)微玩体育辅助器辅助器是一...
专业一下!九九联盟辅助神器,随... 专业一下!九九联盟辅助神器,随意玩俱乐部辅助,本来是真的有挂(哔哩哔哩)亲,关键说明,随意玩俱乐部辅...
解密一下!山西奇迹打锅子辅助,... 解密一下!山西奇迹打锅子辅助,新老夫子较二八年,果然真的是有挂(哔哩哔哩)1、打开软件启动之后找到中...
开挂一下!开心泉州小程序辅助哪... 开挂一下!开心泉州小程序辅助哪里查看,微信小游戏破解版,竟然真的有挂(哔哩哔哩)1、开心泉州小程序辅...
解迷一下!欢乐茶馆脚本辅助,四... 解迷一下!欢乐茶馆脚本辅助,四川家园辅助软件,本来存在有挂(哔哩哔哩)1、四川家园辅助软件辅助器安装...
科普一下!佛手在线辅助器苹果版... 科普一下!佛手在线辅助器苹果版,神殿娱乐控制系统,好像是真的有挂(哔哩哔哩)1、佛手在线辅助器苹果版...