如何在循环中正确释放jstring?

2024-05-07

我的应用程序需要使用jni。逻辑如下:

void myJniFunc(JNIEnv *env, jclass clazz, jobjectArray items) {
    int count = 10;
    struct MyObj *myObjArray = (struct MyObj*)malloc(sizeof(struct MyObj) * count);
    for (i = 0; i < count; i++) {
        jobject obj = (*env)->GetObjectArrayElement(env, items, i);
        jfieldID fieldId = ...;
        jstring jstr = (*env)->GetObjectField(env, obj, fieldId);
        myObjArray[i].name = (*env)->GetStringUTFChars(env, jstr);
        (*env)->DeleteLocalRef(env, obj);
        // Location A
    }

    // some code which will use myObjArray
    process(count, myObjectArray);

    // Location B
}

通过 JNI 文档,GetStringUTFChars 返回的数组应该使用

(*env)->ReleaseStringUTFChars(env, jstr, myObjArray[i].name);
(*env)->ReleaseLocalRef(env, jstr);
  1. 如果我在位置 A 释放返回的数组,则 myObjArray.name 将为空
  2. 如果我在位置 B 释放返回的数组,因为我将保留 jstring 的引用,那么将会发生“无法添加到 JNI 本地引用表(有 512 个条目)”

我的问题是: 如果我想正确释放jstring该怎么办?


由于您的循环正在创建本地引用 (GetObjectField),因此您需要在循环中释放它 (DeleteLocalRef),否则您将遇到本地引用的限制。您必须在两次调用之间完全处理 Java 字符串。

由于您希望保留字符串的字节以供在循环之外使用,因此需要复制这些字节,因为必须在释放字符串引用之前释放 JVM 的固定(或临时副本)(GetStringUTFChars) (ReleaseStringUTFChars)。

因此循环内字符串的顺序必须是:

  1. GetObjectField
  2. GetStringUTFChars
  3. 制作你自己的副本
  4. ReleaseStringUTFChars
  5. DeleteLocalRef

注:与GetStringUTFChars您将获得一个指向 Java 字符串的修改后的 UTF-8 编码的指针。这里有两点:

  1. 您的代码应该能够处理修改后的 UTF-8 编码字符。 (它每个字符有 1 到 6 个字节,并以一种特殊的方式对 NUL 进行编码。)
  2. 文档没有说明数组是否以 0 结尾。您可以使用GetStringUTFLength获取修改后的 UTF-8 编码中的字节数,不包括任何 0 终止符。 (各种 JNI 实现和The Book https://rads.stackoverflow.com/amzn/click/com/0201325772请同意该数组以 0 结尾。)如果您想使用终止符制作自己的副本,请务必为终止符添加空间。

如果您想使用 UTF-16 编码,请使用GetStringChars and GetStringLength。在这种情况下,数组肯定没有终止;它使用内部计数和字符串字节,无需任何转换。

或者,如果您想更改字符集,例如真正的“UTF-8”、“ASCII”、“CP437”或“Windows-1252”或您的代码可以处理的其他字符集,请使用String.getBytes过载或Charset班级。使用Charset如果您想控制如何处理目标字符集中不支持的字符,请使用 .class 。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在循环中正确释放jstring? 的相关文章

  • 使用 Android 前台服务为 MediaPlayer 创建通知

    问题就在这里 我目前正在开发一个应用程序 该应用程序必须提供 A 广播播放器 来自 URL 的 AAC 直播 还有一个播客播放器 来自 URL 的 MP3 流 该应用程序必须能够在后台运行 Android 服务 并通过以下方式向用户公开持续
  • Android - 如何一次只允许播放一个 MediaPlayer 实例?

    我正在尝试创建一个简单的 Sound board Android 应用程序 使用 ListView 项目作为按钮 顺便说一句 我是一个新手程序员 我的想法是 我按下一个按钮 就会播放一个特定的声音文件 如果我在播放声音时按下任何按钮 它应该
  • 如何更新 Firebase 中的节点密钥?

    如何重命名14 04 2017 node 没有用于重命名节点的 API 您必须获取节点的值 使用新名称将其保存到数据库并删除旧节点
  • Firebase Analytics 禁用受众国家/地区跟踪

    我正在开发一个严格不允许位置跟踪的应用程序 我想使用 Firebase Analytic 的其他功能 例如 PageTransitions 和 Crashalitics 但如果我无法禁用受众位置跟踪 我就无法使用其中任何功能 这是我在 An
  • Android:“dp”到“px”转换?

    我正在读这篇文章 http developer android com guide practices screens support html http developer android com guide practices scre
  • Android libgdx 首选项丢失

    我在 Libgdx 引擎中创建了 Android 游戏 一段时间后 我注意到在某些应用程序杀手中杀死该应用程序后 或者如果我在 Android 设置中执行 强制关闭 操作 我保存到首选项中的游戏选项就会丢失 有办法防止这种情况吗 我从来没有
  • (Ionic 2)尝试回退到 Cordova-lib 执行时发生错误:TypeError:无法读取未定义的属性“then”

    Edit 使用 ionic 2 时会发生这种情况 我知道它还不稳定 但我认为可能有一些解决方案 因为其他人似乎没有遇到这个问题 Edit end 由于某种原因 我在尝试使用 ionic build android 和 ionic build
  • 接近语法错误(代码1)插入Android SQLite

    我正在创建一个通讯录应用程序 用户可以在其中输入姓名 电子邮件地址和号码 我希望将此数据保存在数据库中 但我似乎无法使插入方法起作用 我收到的错误是 android database sqlite SQLiteException near
  • 线程自动利用多个CPU核心?

    假设我的应用程序运行 2 个线程 例如渲染线程和游戏更新线程 如果它在具有多核 CPU 当今典型 的移动设备上运行 我是否可以期望线程在可能的情况下自动分配给不同的核心 我知道底层操作系统内核 Android linux内核 决定调度 我的
  • 请求位置更新参数

    这就是 requestLocationUpdates 的样子 我使用它的方式 requestLocationUpdates String provider long minTime float minDistance LocationLis
  • 在 Jetpack Compose 中启动动画矢量 Drawable

    我有一个动画矢量可绘制R drawable my anim 我想在 Jetpack Compose 中展示并开始 可绘制对象显示 渲染正确 但动画未启动 这是撰写视图 Composable fun SplashView Surface mo
  • ROOM迁移过程中如何处理索引信息

    CODE Entity tableName UserRepo indices Index value id unique true public class GitHubRepo PrimaryKey autoGenerate true p
  • MediaCodec 创建输入表面

    我想使用 MediaCodec 将 Surface 编码为 H 264 使用 API 18 有一种方法可以通过调用 createInputSurface 然后在该表面上绘图来对表面中的内容进行编码 我在 createInputSurface
  • 检查 Android 手机上的方向

    如何查看Android手机是横屏还是竖屏 当前配置用于确定要检索的资源 可从资源中获取Configuration object getResources getConfiguration orientation 您可以通过查看其值来检查方向
  • 使用 Matrix.setPolyToPoly 选择位图上具有 4 个点的区域

    我正在 Android 上使用位图 在使用 4 个点选择位图上的区域时遇到问题 并非所有 4 点组都适合我 在某些情况下 结果只是一个空白位图 而不是裁剪后的位图 如图所示 并且 logcat 中没有任何错误 甚至是内存错误 这是我用来进行
  • Android Studio:无法启动守护进程

    当我尝试在 Android Studio 中导入 gradle 项目时 遇到以下错误 Unable to start the daemon process This problem might be caused by incorrect
  • 如何创建像谷歌位置历史记录一样的Android时间轴视图?

    我想设计像谷歌位置历史这样的用户界面 我必须为我正在使用的应用程序复制此 UIRecyclerView 每行都是水平的LinearLayout其中包含右侧的图标 线条和视图 该线是一个FrameLayout具有圆形背景和半透明圆圈Views
  • 通过 ADB 拔出设备:“找不到服务”

    我必须测试我的应用程序在打瞌睡模式下的行为 根据文档 https developer android com training monitoring device state doze standby html testing doze 我
  • 将 JSON 参数从 java 发布到 sinatra 服务

    我有一个 Android 应用程序发布到我的 sinatra 服务 早些时候 我无法读取 sinatra 服务上的参数 但是 在我将内容类型设置为 x www form urlencoded 之后 我能够看到参数 但不完全是我想要的 我在
  • 如何删除因 Google Fitness API 7.5.0 添加的权限

    将我的 play services fitness api 从 7 0 0 更新到 7 5 0 后 我注意到当我将新版本上传到 PlayStore 时 它 告诉我正在添加一个新权限和 2 个新功能 我没有这样做 有没有搞错 在做了一些研究来

随机推荐

  • 在Python中为什么ifrank:比ifrank!= 0更快:

    当我改变的时候 for i in range 0 100 rank ranks i if rank 0 pass to for i in range 0 100 rank ranks i if rank pass 我发现第二个代码效率更高
  • 使用 qTip2 确认工具提示对话框?

    因此 当用户单击删除按钮时 我尝试创建一个小型确认对话框 内联 工具提示 我想象它看起来有点像这样 但带有小文本和 确定 和 取消 按钮 但我不是来问如何设计它的 我更喜欢使用 qTip2 作为该工作的插件 但如果你有更好的选择 我也会选择
  • SQL Server 2008 中 CLR 中的线程

    我有一个CLR运行在下面的进程SQL Server2008 它构建了多个表数据的缓存以保存在静态类中以供其他调用稍后使用 我的问题是 我可以通过生成线程来加载缓存中的每个数据集 表来改进加载此缓存的过程吗 我过去一直回避这一点 因为各种帖子
  • AutoCompleteTextView sqlite填充异常

    我的第一篇文章只有不到一半的文字 因此是第二篇 完整的 文章 我正在开发一个测试应用程序 使用 sqlite 填充两个 AutoCompleteTextView 我正在使用汽车制造商和模型进行测试 自动完成的 使自动完成 模型自动完成 ma
  • Android 中无网络、断线的情况如何处理?

    我有一个应用程序需要连接到 Internet 才能执行某些操作 但当没有可用的 Internet 时 它会崩溃 我读到 如果没有互联网 我需要使用 try catch 括号 我尝试使用它 正如您在 AsyncTask 中看到的那样 但它不起
  • 使用 Task.Run() 写入控制台失败

    我的一位同事发现我们的代码存在问题 花了一段时间才弄清楚究竟发生了什么 但可以通过这个简单的示例来最好地证明这一点 Fails class Program static void Main string args Task Run gt C
  • Android 2.x 天城文 unicode 问题

    我正在尝试使用以下代码支持 android 2 x 的梵文字体 即使 android 2 x 无法渲染梵文字体 除了 raswa 和 dirga 存在一些问题之外 代码工作正常 是否有可能在 android 2 x 中获得正确的梵文表示形式
  • 无法将 Visual Studio 项目中的多个文件提交到 subversion

    几周以来 我在使用 Subversion 时遇到了一些问题 当我尝试从 Visual Studio 2017 项目提交文件时 有些文件无法提交到我的 Visual SVN 服务器 准确地说 项目文件夹中的所有文件 如 cs config c
  • 使用 libx264 为 Raspberry pi 编译 Xuggler 时的问题 #2

    我正在尝试编译Xuggler http www xuggle com xuggler 对于 Raspberry Pi 在 Debian 操作系统上运行 又名 Raspbian 我遵循了可用的 基本构建说明 here http www xug
  • 是否有一个“AcceptsOneWidget”也“ProvidesResze”(除了“ScrollPanel”)?

    我有一个复合材料可以扩展ResizeComposite并有一个DockLayoutPanel作为它的根 我可以直接贴进去RootLayoutPanel它之所以有效是因为DockLayoutPanel ProvidesResize 但是 我想
  • 如何监控“即时发生”生成的 Google Alert RSS feed?

    我有一个 Google 快讯 我将其设置为以 RSS 源形式发送当它发生的时候 But 轮询 RSS feed 是获取 RSS feed 的唯一方法 or 当 Feed 是从 Google 发布时 有没有办法收到 Google 警报的通知
  • Flex 与 ActionScript

    我正在尝试构建 实现一个 Flash 视频播放器来播放视频 我研究了 Flex 并仅使用 VideoElement 构建了一个基本应用程序 它在没有静态链接库的情况下编译为 41k 在链接库时编译为 300k 我生成了报告 但仍然不确定为什
  • 如何通过 HttpContext 访问 Blazor Server .Net 6 中的 cookie?

    不幸的是 有关在 Blazor Server 中访问 c ookie 的教程和之前的 StackOverflow 答案似乎在新的 Net 版本中变得无效 例如 我无法获得以下任一答案 根据 net 6 中没有的评论来判断 如何在服务器端 B
  • cuda中内核的并行执行

    可以说我有三个全局数组 它们已使用 cudaMemcpy 复制到 GPU 中 但 c 中的这些全局数组尚未使用 cudaHostAlloc 分配 以便分配页面锁定的内存 而不是简单的全局分配 int a 100 b 100 c 100 cu
  • 在 Linux 2.6.21 (glibc 2.3.5) 上进行 ARP 和反向 ARP

    我需要在任意 IP 网络上存储对第三方设备的持久引用 其中设备的 IP 地址可能是静态的或由 DHCP 随机分配 我不控制网络上的设备 也不能依赖 DNS 和其他现有的或与设备一起使用的临时网络协议 所以我被指示使用硬件地址和 ARP 进行
  • Haskell 中函数和函子有什么区别?只有定义吗?

    在 Haskell 中 当编写函数时 这意味着我们将某个东西 输入 映射到另一个东西 输出 我尝试 LYAH 来理解 Functor 的定义 看起来和普通 Functor 一样 函数被称为函子有什么限制吗 Functor 是否允许有 I O
  • 将组合字符串和数字输入的元胞数组写入文本文件

    考虑以下 DateTime 2007 01 01 00 00 2007 02 01 00 00 2007 03 01 00 00 Headers Datetime Data Dat 100 200 300 Data DateTime num
  • 使用 mvel 检查 List 中是否存在元素

    我随身带着一份清单 清单就像 List
  • Apache Kafka 消费者组的偏移量如何过期?

    当我注意到一些奇怪的行为时 我正在对一个旧主题进行一些测试 阅读 Kafka 的日志时 我注意到这条 删除了 8 个过期的偏移量 消息 GroupCoordinator 1001 Stabilized group GROUP NAME ge
  • 如何在循环中正确释放jstring?

    我的应用程序需要使用jni 逻辑如下 void myJniFunc JNIEnv env jclass clazz jobjectArray items int count 10 struct MyObj myObjArray struct