设为首页
收藏本站
切换到窄版
登录
立即注册
找回密码
搜索
搜索
本版
帖子
用户
快捷导航
论坛
BBS
C语言
C++
NET
JAVA
PHP
易语言
数据库
IE盒子
»
论坛
›
IE盒子
›
JAVA
›
Java Native Interface使用指南(持续更新)
返回列表
发帖
查看:
129
|
回复:
1
Java Native Interface使用指南(持续更新)
[复制链接]
任术明
任术明
当前离线
积分
23
3
主题
13
帖子
23
积分
新手上路
新手上路, 积分 23, 距离下一级还需 27 积分
新手上路, 积分 23, 距离下一级还需 27 积分
积分
23
发消息
发表于 2023-1-7 21:54:34
|
显示全部楼层
|
阅读模式
Java Native Interface使用指南(持续更新)
0.前言
鉴于我们经常需要使用java的本地方法调用C/C++进行编写程序,但是经常不知道如何在C++侧解析来自java的变量和构造java需要的变量作为返回,不知道如何释放jni对象以至于造成内存泄漏。这里对java的本地方法做一个总结,方便自己进行查阅,加快编码速度。
1.Java Native Interface官网
https://docs.oracle.com/javase/8/docs/technotes/guides/jni/
官网第一章镇楼,未尽处请参阅官网爸爸。
2.变量类型对应关系
2.1 基本数据类型
2.2 引用数据类型
2.3 变量类型签名关系
比如:
后续看是否有必要在这里补充各种数据类型的签名写法
(1)基本数据类型上面已经有了
(2)数组是中括号:[
(3)函数入参类型使用小括号包围
(4)引用类型使用L+包名路径(其中.替换为/)
3.各种java类型和C++类型的相互转换示例代码
3.1 String用法
解析:
const char *stringPtr = env->GetStringUTFChars(jString, nullptr);
std::string cppString(stringPtr);
释放:
env->ReleaseStringUTFChars(jString, stringPtr);
env->DeleteLocalRef(jString);
4.Android JNI注意的地方
5.一些小知识
5.1 可以删除空引用,放心删除引用,不必要事先进行判空
对于这样是没必要的:
if (object != nullptr) {
env->DeleteLocalRef(object);
}
直接:
env->DeleteLocalRef(object);
5.2 实现非JNI函数处理java数据,通过JavaVM获取JNIEnv(无中生有?)
5.2.1初始化JavaVM
JavaVM *g_javaVm = nullptr; // 理论上,每个进程可以有多个 JavaVM,但 Android 只允许有一个。
// 初始化时操作, 通过初始的JNIEnv获取全局的JavaVM
// 线程不允许共用env环境变量,但是JavaVM指针是整个jvm共用的,所以可以通过下面的方法保存JavaVM指针,在线程中使用
int ret = env->GetJavaVM(&g_javaVm);
if (ret != JNI_OK || g_javaVm == nullptr) {
printf("env->GetJavaVM(&g_javaVm) error code(%d) or g_javaVm(%p) == nullptr!!!", ret, g_javaVm);
return JNI_ERR;
}5.2.2使用JavaVM在任意线程中获取JNIEnv
// 从全局的JavaVM中获取到环境变量
JNIEnv* env = nullptr;
g_javaVm->AttachCurrentThread(&env, nullptr);
if (env == nullptr) {
g_javaVm->DetachCurrentThread();
printf("env == nullptr");
}
g_javaVm->DetachCurrentThread();5.2.3删除全局JavaVM
if (g_javaVm != nullptr) {
printf("clean g_javaVm!");
g_javaVm = nullptr;
}5.3 全局引用的使用
5.3.1初始化全局引用,各个线程都可使用
jobject g_javaObject = nullptr;
// jobject变量也不允许在线程中共用,因此需要创建全局的jobject对象在线程中访问该对象
g_javaObject = env->NewGlobalRef(object);
if (g_javaObject == nullptr) {
printf("env->NewGlobalRef(object) error!!!");
return JNI_ERR;
}5.3.2使用全局引用
// 使用
env->CallIntMethod(g_javaObject , methodId, var1, var2);5.3.3删除全局引用
if (g_javaObject != nullptr) {
printf("clean g_object!");
env->DeleteGlobalRef(g_javaObject);
g_javaObject = nullptr;
}
回复
使用道具
举报
王子哥
王子哥
当前离线
积分
20
5
主题
9
帖子
20
积分
新手上路
新手上路, 积分 20, 距离下一级还需 30 积分
新手上路, 积分 20, 距离下一级还需 30 积分
积分
20
发消息
发表于 2025-5-19 05:47:18
|
显示全部楼层
撸过
回复
使用道具
举报
返回列表
发帖
高级模式
B
Color
Image
Link
Quote
Code
Smilies
您需要登录后才可以回帖
登录
|
立即注册
本版积分规则
发表回复
回帖后跳转到最后一页
快速回复
返回顶部
返回列表