JNI与NDK

本文详细介绍了Java Native Interface (JNI) 和 Android NDK 的概念、作用及调用步骤。对比了JNI与NDK的不同之处,并提供了C/C++代码示例说明如何在Android环境中使用JNI与本地代码交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JNI

定义 :

Java Native Interface,即 Java本地接口

作用

使得Java 与 本地其他类型语言(如C、C++)交互

注意:

  • JNIJava 调用 Native 语言的一种特性
  • JNI 是属于 Java 的,与 Android 无直接关系

调用实现步骤:

  1. Java中声明Native方法(即需要调用的本地方法)
  2. 编译上述 Java源文件javac(得到 .class文件)
  3. 通过 javah命令导出JNI的头文件(.h文件)
  4. 使用 Java需要交互的本地代码 实现在 Java中声明的Native方法

    Java 需要与 C++ 交互,那么就用C++实现 JavaNative方法

  5. 编译.so库文件

  6. 通过Java命令执行 Java程序,最终实现Java调用本地代码

NDK

定义 :

Native Development Kit,是 Android的一个工具开发包

NDK是属于 Android 的,与Java并无直接关系

作用

  • 快速开发C、 C++的动态库,并自动将so和应用一起打包成 APK(即可通过 NDKAndroid中 使用 JNI与本地代码(如C、C++)交互。)

  • NDK集成了交叉编译器,并提供了相应的mk文件隔离平台、CPUAPI等差异,开发人员只需要简单修改.mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so

  • NDK提供了一份稳定、功能有限的API头文件声明。

调用实现步骤:

  1. 配置 Android NDK环境

  2. 创建 Android 项目,并与 NDK进行关联

  3. Android 项目中声明所需要调用的 Native方法

  4. 使用 Android需要交互的本地代码 实现在Android中声明的Native方法 。
    比如 Android 需要与 C++ 交互,那么就用C++ 实现 JavaNative方法

  5. 通过 ndk - bulid 命令编译产生.so库文件

  6. 编译 Android 工程,从而实现 Android 调用本地代码

Android工程中C/C++代码解析

native-lib.cpp

#include <jni.h>
#include <string>

extern "C"
JNIEXPORT jstring JNICALL
Java_com_kevin_cpp_MainActivity_stringFromJNI(
        JNIEnv *env,jobject obj ) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}
  • JNIEXPORTNICALLJNIEnvjobject都是JNI标准中所定义的类型或者宏,它们的含义如下:

  • JNIEXPORTJNICALL:他们是JNI中所定义的宏,可以在jni.h这个头文件中查询到;

  • JNIEnv*:表示一个指向JNI环境的指针,可以通过它来访问JNI提供的接口方法。

  • jobject:表示Java对象中的this

注意:JNI调用C或者C++存在区别:

  1. JNI是由C语言定义接口的,JNI通过函数名找函数入口,执行函数里的内容。这和函数用什么语言生成的并没有关系。只要保证函数名称符合JNI的协议。而使用C++要注意的是C++默认生成的函数名称和你写在源文件中的名称并不相同,因为C++要处理函数重载,会在函数名称中加上参数信息,这称为name mangling
    解决方法是定义函数时在前面加上extern"C"修饰,告诉编译器这函数按照C语言方式编译和链接。extern"C"这个声明的真实目的是为了实现C++C及其它语言的混合编程。

  2. C的定义中,env是一个两级指针,而在C++的定义中,env是个一级指针
    C形式需要对env指针进行双重deferencing,而且须将env作为第一个参数传给jni函数。

C代码中:JNI 函数调用由“(*env)->”作前缀,目的是为了取出函数指针所引用的值。

return*env)->NewStringUTF(env,"HelloJNI!");  

C++代码中:JNIEnv 类拥有处理函数指针查找的内联成员函数。

return env->NewStringUTF("HelloJNI!");  

可以发现,C或者C++的实现很类似,但是它们对env的操作方式不同,因此使用CC++来实现同一个JNI方法,它们的区别主要集中在对env的操作上。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值