c++的jni动态注册简单示例(上)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++的jni动态注册简单示例(上)相关的知识,希望对你有一定的参考价值。

参考技术A jni动态注册是性能最优的方案。写这个的原因是jni使用的过程中坑比较多,方便此前没有接触过的朋友快速构架开发编译环境。
如果使用jna,只需要通用的c type函数导出的dll就可以了。如果是android使用的话Android studio自带cmake,这里不多讲。

win10 vs2019 cmake-3.19 idea jdk-8( https://adoptopenjdk.net )

任意的gradle/maven工程。

在源码目录下新建包com,包下新建CppNative.kt:

同样的,在com包下新建Native.java:

我们可以编译此项目,得到class文件,在class目录下:

在java/main下运行 javah -jni com.Native 得到com_Native.h:

在kotlin/main下运行 javah -jni com.CppNative 得到com_CppNative.h

这是jni静态映射需要的头文件。但是动态映射不需要这个头文件,只需要获取一些拿不准的方法签名和参数类型。由于kotlin的实现机制,可以看到kotlin object类实际上是一个单例实现,jni的c函数映射的第二个参数是jobject,而不是jclass类型。如果kotlin的object内的方法想要真正的静态实现只需加入注解: @JvmStatic external fun hello()

在java/main下运行 javap -s com.Native :

在kotlin/main下运行 javap -s com.CppNative :

使用camke的原因是便于跨平台,一般说来我们在linux、windows上都有需求。

使用vs2019(如有需要在visual studio installer上勾选“使用c++的linux开发”,调试linux cpp项目比较方便),新建cmake项目“native-do”:

vs2019默认的cmake项目是一个父CMake项目下包含一个子项目的形式,其实没有必要改,但是为了在windows:msvc和linux:gcc下能够编译同一个项目,简化项目结构,最终项目结构如下:

这里省略了vs调试方面的工作。

其中的jni.h和jni_md.h由对应的jdk文件复制而来,做动态映射的主要工作由jni.cpp完成,而native_do.cpp实现具体函数。所有文件都是utf8 LF格式。

参考 https://android.googlesource.com/platform/development/+/master/samples/SimpleJNI/jni/native.cpp

主要注意 classPathName 和 methods 两个变量,通过 classPathName 指定完整类名(包名+类名), methods 指定方法的映射关系:

native_do.h:

native_do.cpp:

在我们的CMakeLists.txt所在的目录执行;

cmake -B build -S .

cmake --build build --config Release

cmake -B build -S . -DCMAKE_BUILD_TYPE=Release

cmake --build build

这里只是简单的映射了打印字符串方法,关于jni引用参数、回调等映射方式放在下章。

JNI方法注册源码分析(JNI_OnLoad|动态注册|静态注册|方法替换)


文章目录

以上是关于c++的jni动态注册简单示例(上)的主要内容,如果未能解决你的问题,请参考以下文章

我的C语言学习进阶之旅介绍一下NDK开发中关于JNI函数的两种注册方式:静态注册和动态注册

JNI方法注册源码分析(JNI_OnLoad|动态注册|静态注册|方法替换)

Android 动态注册JNI函数

JNI方法注册源码分析(JNI_OnLoad|动态注册|静态注册|方法替换)

JNI方法注册源码分析(JNI_OnLoad|动态注册|静态注册|方法替换)

JNI方法注册源码分析(JNI_OnLoad|动态注册|静态注册|方法替换)