С чего начать ... JNI невероятно привередливый и неумолимый, и если вы не сделаете все правильно, он взорвется. Ваше описание довольно тонкое (пожалуйста, предоставьте более подробную информацию, если это не поможет), но я могу сделать хорошее предположение Есть несколько проблем с вашим подходом. Вы, вероятно, делаете что-то вроде этого:
struct state {
state(jobject thing_) : thing(thing_) {}
~state() { env->DeleteLocalRef(thing); }
jobject thing;
}
Первая проблема заключается в том, что хранение локальных ссылок опасно. Вы не можете висеть на них за пределами текущего кадра JNI. Так что конвертируйте их в глобальные:
struct state {
state(jobject thing_) : thing(env->NewGlobalRef(thing_)) {
env->DeleteLocaLRef(thing_);
}
~state() { env->DeleteGlobalRef(thing); }
jobject thing;
}
Вторая проблема заключается в том, что jobject в основном похож на старый C ++ auto_ptr <> - действительно небезопасно, поскольку его копирование приводит к опасным указателям и двойным освобождениям. Таким образом, вам нужно либо запретить копирование состояния и, возможно, только передать состояние *, либо создать конструктор копирования, который работает:
state(const state& rhs) thing(env->NewGlobalRef(rhs.thing)) {}
Это должно по крайней мере вывести вас на правильный путь.
ОБНОВЛЕНИЕ: Ddor, в отношении локальных и глобальных ссылок, эта ссылка хорошо описывает это: «Локальные ссылки становятся недействительными, когда выполнение возвращается из собственного метода, в котором создана локальная ссылка. Следовательно, собственная ссылка Метод не должен хранить локальную ссылку и ожидать ее повторного использования в последующих вызовах. " Вы можете хранить местные ссылки, но только при строгих обстоятельствах. Обратите внимание, что, в частности, вы не можете передать их другому потоку, что, по-видимому, вы не делаете. Другое дело - существуют ограничения на общее количество локальных ссылок, которые могут быть активными. Этот предел разочаровывает, но он кажется специфичным для JVM. Я советую осторожность и всегда переходить на глобальный.
Я думал, что где-то читал, что вам не нужно удалять jclass, потому что FindClass () всегда возвращает одно и то же, но мне трудно это проверить. В нашем коде мы также всегда преобразуем jclass в глобальную ссылку.
ENV->DeleteLocalRef(this->jclass_state);
Я должен признать незнание семантики перемещения C ++; просто убедитесь, что копия по умолчанию ctor не вызывается и ваше jobject_state не освобождается дважды.
this->jobject_state = state_to_move.jobject_state;
Если ваш конструктор перемещения вызывается вместо конструктора копирования или присваивания, я не знаю, почему вы увидите удаление при уничтожении временного объекта. Как я уже сказал, я не эксперт по семантике перемещения. У меня всегда был конструктор копирования, создающий новый глобал. ссылка.