【问题标题】:Conversion between jboolean* and uint64_t*jboolean* 和 uint64_t* 之间的转换
【发布时间】:2021-06-05 22:14:29
【问题描述】:

我正在尝试将具有 128 个元素(始终)的 jbooleanArray 转换为具有 128 个元素的 bools 的 C++ 数组。

extern "C" {
JNIEXPORT jboolean  Java_com_app_flutter_1app_JNI_loadBufferNative(
        JNIEnv *env, jbooleanArray jMidiNotes) {
    bool midiNotes[128] = {false};
    *reinterpret_cast<uint64_t*>(midiNotes) = *env->GetBooleanArrayElements(jMidiNotes, nullptr);
    *reinterpret_cast<uint64_t*>(midiNotes + 64) = *env->GetBooleanArrayElements(jMidiNotes + 64, nullptr);

我相信GetBooleanArrayElements 会返回jboolean*,而且看起来jboolean 在C++ 中就是uint8_t(奇怪)。

我在这里做错了什么?我遇到了崩溃JNI DETECTED ERROR IN APPLICATION: use of invalid jobject 0x7ff426b390

自从jboolean = uint8_t我也试过了

    *reinterpret_cast<uint64_t*>(midiNotes + 64) = *env->GetBooleanArrayElements(jMidiNotes + 8, nullptr);

但我遇到了同样的崩溃

【问题讨论】:

  • jvm 可能会使用数组中的布尔值进行优化。它可以将这些存储为位图或类似的。
  • 当有问题的对象(据您所知)uint8_t 时,您为什么要使用 uint64_t?似乎是某种失败的秘诀。
  • 我不知道当前的问题是否与严格的别名有关,但你准备与strict aliasing rules 发生冲突。

标签: java android c++ java-native-interface


【解决方案1】:

你不能像这样对对象句柄进行指针运算:

*reinterpret_cast<uint64_t*>(midiNotes + 64) = *env->GetBooleanArrayElements(jMidiNotes + 64, nullptr);

您应该首先使用GetBooleanArrayElements 获取指向数组元素的指针,然后对该指针进行指针运算。例如,这样做:

extern "C" {
JNIEXPORT jboolean  Java_com_app_flutter_1app_JNI_loadBufferNative(
    JNIEnv *env, jbooleanArray jMidiNotes) {
    bool midiNotes[128] = {false};
    jboolean* values = env->GetBooleanArrayElements(jMidiNotes, nullptr);
    std::copy(values, values + 128, midiNotes);

【讨论】:

    猜你喜欢
    • 2015-05-25
    • 1970-01-01
    • 2015-12-07
    • 2011-09-13
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多