背景
无论在开发Android项目还是Java项目时,为了复用现有的C/C++代码,或者添加破解的难度,会使用C/C++开发一部分核心的功能。
JVM与C的接口使用JNI,不再多述。后面会有文章进行详细的说明。本文中枫竹梦只说明环境的搭建,以及一个Hello JNI的demo。
IntelliJ IDEA设置
新建一个项目
命名为HelloJNI
- 新建目录
jni
,用于存储生成的头文件。 - 新建目录
lib
,用于存放C/C++编译的动态库文件。
并在src新建Hello类
public class Hello {
static {
System.loadLibrary("hello");
}
public native void sayHello();
public static void main(String[] args) {
new Hello().sayHello();
}
}
下一步需要生成C语言头文件。为了方便后面的生成或者更新,这里添加将生成过程添加为一个快捷工具。在Preferences
–Tools
–External Tools
下新建。
Name和Description随意,Name会在下面用到。重要的的下面三个:
- Program内容
$JDKPath$/bin/javah
- Arguments内容
-classpath $OutputPath$ -d ./jni $FileClass$
- Working directory内容
$ProjectFileDir$
。
在类Hello
上点击鼠标右键—External Tools
–GenerateHeader
生成头文件,在jni
目录就生成Hello.h
的文件了。
CLion设置
在CLion同样新建项目,命名为hello
,Language standard选择哪个都可以,Library type选择shared
在Preferences
–Build, Execution, Deployment
–CMake
中将Build directory修改为build/debug
,同样添加Release并进行类似的设置。
设置目录结构如下:
build
是编译过程生成目录jni
为在IntelliJ IDEA下生成的,需要复制过来src
目录是源码目录
根目录下的CMakeLists.txt的内容为:
cmake_minimum_required(VERSION 3.17)
project(hello)
set(CMAKE_CXX_STANDARD 20)
find_package(JNI REQUIRED)
include_directories(${JNI_INCLUDE_DIRS})
include_directories(jni)
add_subdirectory(src)
src/CMakeLists.txt内容为:
add_library(hello SHARED hello.c)
src/hello.c的内容为:
#include "Hello.h"
#include <jni.h>
#include <stdio.h>
JNIEXPORT void JNICALL Java_Hello_sayHello (JNIEnv *env, jobject obj) {
printf("Hello JNI!\n");
}
在编译之前需要确保已经设置好了JAVA_HOME
环境变量。
编译Debug版本,正常会生成文件build/debug/src/libhello.dylib
。枫竹梦是在Mac下编译,如果在Linux编译生成的是libhello.so。
此时CLion的工作已经完成。
编译与运行
将上面生成的libhello.dylib
或者libhello.so
复制到IntelliJ IDEA下的lib
目录。
在编辑运行配置,选择右上角的Modify options
–Add VM options
,添加-Djava.library.path=$ProjectFileDir$/lib
最后运行Java项目,会打印Hello JNI。至此,配置已经完成。
后面更新native接口进需要重新生成头文件,并将jni目录复制到CLion中。
如果只是更新native的实现,需要将动态库从CLion项目中复制到IntelliJ IDEA中。
祝使用愉快,如果有遇到问题请留言,有更好的使用方式也欢迎讨论。
vx搜:极客Furzoom,关注获取第一手资料。