JNI:实现流程/数据类型映射关系/参数传递/返回值

本文详细介绍如何使用JNI(Java Native Interface)进行Java与C/C++的交互,包括代码块定义、头文件生成、C/C++函数实现、mk文件配置、so库编译与加载,以及数据类型映射和函数指针使用等核心内容。

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

步骤

1. java层静态代码块:public static native String fun(String str);
2. 生成包名.类名.h头文件:javah -classpath bin/class; android.jar -d jni 包名.类名
-classpath:把java代码编译成的.class的目录
-d:输出目录
3. 创建.cpp文件:复制头文件中的函数名再实现函数
4. mk文件:编译脚本
LOCAL_MODULE := xxx     // so名字
LOCAL_SRC_FILES := xxx   // c代码文件
5. 编译:ndk-build
6. 导入so:System.loadLibrary("xxx");
7. 调用fun方法

java数据类型与native数据类型映射

除了void对应void,其它的都是在原类型上加j,比如int对应jint。

编写native

1. Java类型转native类型:在基本类型上加j
2. 函数指针:JNIEnv *env
3. 获取java层传过来的参数
	a. 整型
	b. 字符串转换
	// 生成指针
	const char *p = (*env)->GetStringUTFChars(env, str, NULL); // 默认值NULL
	// 释放指针
	(*env)->ReleaseStringUTFChars(env, str, p);
	c. 数组拷贝
	public static native int[] fun(int[] arr);
	jint array[5];
	// 数组复制
	(*env)->GetIntArrayRegion(env, 0, 5, arr);// 从0到5
	(*env)->SetIntArrayRegion(env, 0, 5, arr);
	d. 数组指针
	// 生成数组指针
	jint *p = (*env)->GetIntArrayElements(env, arr, NULL);
	// 数组长度
	jsize len = GetArrayLength(env, arr);
	(*env)->ReleaseStringUTFChars(env,arr,p);
4. 返回值给java层
	a. 基本类型直接return数据
	b. 数组需要NewxxxArray和SetxxxArrayRegion创建和赋值再return
	c. 类或结构体:搜索类FindClass,获取构造函数GetMethodID,创建实例NewObject,获取成员属性GetFieldID,设置属性SetXXXField,最后return