Мне нужно было бы передавать данные между моими объектами Java и внешней программой OCaml через интерфейс JNI, но у меня проблемы с доступом к полям объектов в нативном коде.
На стороне Java у меня есть классс несколькими полями:
public class GPSState {
int fix;
double course;
double hmsl;
...
}
Я передаю объект jstate
класса GPSState
в часть C, где я пытаюсь установить для его полей соответствующие значения, предоставленные внешней программойкоторые сохраняются в локальной структуре state
:
jclass cls;
jfieldID fid;
cls = (*env)->GetObjectClass( env, jstate);
fid = (*env)->GetFieldID( env, cls, "fix", "I");
(*env)->SetIntField( env, cls, fid, state.fix);
fid = (*env)->GetFieldID( env, cls, "course", "D");
(*env)->SetDoubleField( env, cls, fid, state.course);
fid = (*env)->GetFieldID( env, cls, "hmsl", "D");
(*env)->SetDoubleField( env, cls, fid, state.hmsl);
...
Из отладочных отпечатков я узнал, что класс успешно расположен, а поля fix
и course
правильно определены и установлены.Но после выполнения вызова SetDoubleField
в поле course
, что подтверждается отладочной печатью сразу после строки вызова, я всегда получаю фатальную ошибку SIGSEGV, когда пытаюсь получить доступ к любому другому полю:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x01109720, pid=11665, tid=3079347056
#
Позже я обнаружил, что когда я перемещаю код, управляющий полем course
, в самый конец функции C, которая устанавливает поля, ошибка исчезает, и все поля устанавливаются, как и ожидалось, без каких-либо проблем.
Я пытался запустить код на другом компьютере с другой реализацией JRE, но результат был таким же, за исключением того, что произошла ошибка после установки первого поля fix
(перемещение соответствующего бита кода вконец функции снова «решил» проблему).
Теперь я знаю, что каким-то образом испортил память, но не могу понять, где и как.Я следовал главе «Поля и методы» в Руководстве программиста JNI, чтобы проверить возможные ошибки, но мне кажется, что я делаю все по книге.Неужели кто-то более опытный будет так добр и укажет, где может быть проблема?