JRE SIGSEGV при запуске собственного кода JNI - PullRequest
1 голос
/ 19 сентября 2011

Мне нужно было бы передавать данные между моими объектами 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, чтобы проверить возможные ошибки, но мне кажется, что я делаю все по книге.Неужели кто-то более опытный будет так добр и укажет, где может быть проблема?

1 Ответ

2 голосов
/ 19 сентября 2011
(*env)->SetIntField( env, cls, fid, state.fix);

Это не выглядит правильно.Вы пытаетесь установить поле экземпляра объекта, но передаете cls вместо jstate в качестве объекта для доступа.Вместо этого следует использовать следующее:

(*env)->SetIntField( env, jstate, fid, state.fix);

Внести соответствующие изменения и для других ваших вызовов Set<type>Field.

...