page contents

java jni教程——JNI基础简介

本文讲述了Java jni教程——JNI基础简介!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

attachments-2023-06-lpxv4cKo647a9af6c64c1.png本文讲述了Java jni教程——JNI基础简介!具有很好的参考价值,希望对大家有所帮助。一起跟随六星小编过来看看吧,具体如下:

JNI是Java Native Interface的缩写,俗称Java本地接口,是Java语言提供的用于Java和C/C++相互沟通的机制,Java可以通过JNI调用本地的C/C++代码,本地的C/C++的代码也可以通过JNI调用Java代码。

那什么场景下可能会用到JNI呢?1、需要提升性能时,比如说做一些底层的开发,例如音视频处理之类的,通常都会用到JNI。2、增加破解难度,例如需要提升代码的保护级别,需要将一些敏感信息放到底层隐藏起来。3、需要使用到一些较为成熟的底层C/C++库时。

NDK

要在安卓上使用JNI就需要用到NDK,而NDK一系列工具的集合,它提供了一系列的工具帮助开发者快使得C/C++代码能够交叉编译生成可在安卓系统上运行的动态库库或者静态库。例如我们想要将基于C的音视频处理库FFmpeg移植到安卓平台上使用的话就需要用到NDK进行交叉编译。

动态库和静态库

1、静态库

静态库是指在链接阶段,编译器将汇编生成的.o目标文件与库文件一起链接打包到可执行文件中,或者说一起链接生成最后的可执行文件。因此对应的链接方式称为静态链接。

因为静态库是在编译期间连接库文件的,所以静态库存在着可执行文件体积较大,更新维护不方便等问题。

2、动态库

动态库又叫共享库,或动态链接库。动态库在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入,不同的应用程序如果要调用同一个库,在内存中只需要有一份该共享库即可,这样就规避了空间浪费的问题。而且动态库是在程序运行时才被载入,所以相对静态库来说动态库还具有更新、部署方便等优点。正因为动态库的这些优点,所以目前的大多数的SDK普遍才有动态库的方式。

一个简单的JNI函数

我们使用Android Studio新建一个Native C++工程,系统将自动为我们创建一个最简单的JNI函数,当然不同的包名,生成的JNI函数名不一样,例如:

extern "C" JNIEXPORT jstring JNICALL

Java_com_fly_jnitest_MainActivity_stringFromJNI(

        JNIEnv* env,

        jobject obj) {

    std::string hello = "Hello from C++";

    return env->NewStringUTF(hello.c_str());

}

1、extern "C" 在JNI函数中首先出现的是extern "C",它是什么意思呢?这个其实写过C/C++代码的人估计都知道,就是为了在C++兼容C代码的,避免编绎器按照C++的方式去编绎C函数。这是因为在C++中是支持函数重载的,所以在C++中函数的识别方式是通过:函数名,函数的返回类型,函数参数列表三者组合来完成的;而在C中是不支持函数重载的,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。因此需要通过extern "C"来使C++能够调用C写作的库文件。

2、jstring 这个没什么好说的,这个就是函数的返回值。

3、JNIEXPORT JNIEXPORT是一个宏,它们在不同的平台有着不同的定义,它的主要作用是保证在本库中声明的方法,能够在其他项目中可以被调用。例如attribute___((visibility ("default"))) 表示外部可见,类似于public修饰符 (即:可以被外部调用),而attribute___((visibility ("hidden")))表示隐藏,类似于private修饰符 (即:只能被内部调用)。

4、JNICALL JNICALL也是一个宏,同样在不同的平台也有着不同的定义,用来表示函数的调用规范(如:__stdcall),目前在linux平台还是是空定义。

4、函数名 在上面的例子中函数名是Java_com_fly_jnitest_MainActivity_stringFromJNI,这是一个静态注册的函数名,它是与对于的Java方法有着对应关系的,他们的对应关系是:

Java_<包名>_<类名>_<方法名>

5、JNIEnv JNIEnv* 是指向JVM函数表的指针,JNIEnv代表了Java环境,通过JNIEnv*就可以对Java端的代码进行操作,例如创建Java对象、访问Java对象方法、获取Java对象的属性等。总之它是Java方法与C/C++方法沟通的桥梁。

需要注意的是:一个JNIEnv指针仅在其相关联的线程中有效。不能将这个指针从一个线程中传递给另一个线程,或者在多线程中缓存和使用它。Java虚拟机在同一个线程传递给本地方法相同的JNIEnv指针,但是从不同线程中调用本地方法时传递的是不同的JNIEnv指针。

6、jobject jobject 代表了定义native函数的Java类的对象实例,如果对于的方法是一个静态方法,则是jclass。

更多相关技术内容咨询欢迎前往并持续关注六星社区了解详情。

想高效系统的学习Java编程语言,推荐大家关注一个微信公众号:Java圈子。每天分享行业资讯、技术干货供大家阅读,关注即可免费领取整套Java入门到进阶的学习资料以及教程,感兴趣的小伙伴赶紧行动起来吧。

attachments-2023-03-2AoKIjPQ64014b4ad30a3.jpg

  • 发表于 2023-06-03 09:44
  • 阅读 ( 144 )
  • 分类:Java开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1316 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章