Javac 根据先前限定为“本机”的方法自动生成函数,并将其所属的类和包名称纳入函数名称中。
仔细观察生成的函数,您会发现一些乍一看可能很奇怪的东西。
我们的整数变成了“jint”。为什么即使原始 Java 函数没有任何参数,我们所有的函数都有“JNIEnv*”和“jobject”?
更令人困惑的是,“JNIEXPORT”和“JNICALL”到底是什么意思?
我们先从最容易解释的“jint”和“jobject”开始。 “jint” 是 Java 整数类型的 C/C++ 表示。
“jobject” 类似,但针对的是 Java 对象。您在函数中看到 保加利亚号码数据 的第一个“jobject”参数代表对象本身。
现在来解释一些比较复杂的内容。 JNIEnv* 是指向 Java 本机接口环境的指针。
此 JNIEnv* 指针允许与 Java 交互。它使得访问对象的方法、初始化新对象等成为可能。
“JNIEXPORT”和“JNICALL”提供JNI调用函数所需的信息。 JNIEXPORT 确保该函数放在函数表上,以便 JNI 可以找到它。
JNICALL 确保导出的函数可供 JNI 使用,以便可以从我们的 Java 应用程序内部调用它。
所有这些类型和编译器宏都来自“jni.h”头文件,该文件可以在生成的头文件的顶部看到。
现在我们所拥有的只是一个头文件。让我们创建一个.cpp文件来实现生成的头文件。
创建一个.cpp文件,最好与src/main/cpp文件夹中生成的.h文件同名。 就我而言,这是com_matthijs_kropholler_jniarticle_MyNativeObject.cpp。
接下来,实现 C++ 方法。
步骤 3:编译 C++ 代码
生成的标题已经实现并准备进行编译。这可以手工完成。需要手动编译 C++ 代码并将其链接在一起。
这可以通过脚本来完成,例如 Bash 脚本,但长期管理可能困难。幸运的是,CMake 可以解决这个问题,因为它将生成编译和粘合本机代码所需的文件。
CMake 在 C/C++ 世界中非常流行,而且这是有充分理由的。 CMake 的主要优势之一是它可以生成特定于平台的 makefile,并且与多种编译器兼容。
在我们的C++ 代码所在的cpp文件夹中,创建一个名为CMakeLists.txt的新文件。该文件包含我们的 CMake 说明。