Reputation: 13
I'd need to transfer data between my Java objects and an external OCaml program via JNI interface but I have troubles to access object fields in the native code.
On the Java side, I have a class with several fields:
public class GPSState {
int fix;
double course;
double hmsl;
...
}
I'm passing an object jstate
of the GPSState
class to the C part, where I'm trying to set its fields to respective values provided by the external program which are saved in local struct 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);
...
From debug prints I've learned that class is successfuly located and the fix
and course
fields are properly identified and set. But after the execution of SetDoubleField
call on course
field, which is confirmed by a debug print immediately following the call line, I always get SIGSEGV fatal error when I try to access any other field:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x01109720, pid=11665, tid=3079347056
#
Later I've found out, that when I move the code manipulating the course
field to the very end of the C function which sets the fields, the error disappears and all fields are set as expected without any problems.
I've tried to run the code on another machine with another JRE implementation but the result was the same, except the error then occured after setting the first fix
field (moving the respective bit of the code to the end of the function "solved" the problem again).
Now, I know I'm somehow messing up the memory but I can't figure out where and how. I've followed the Fields and Method chapter in JNI Programmer's Guide to check for possible mistakes but it seems to me that I do everything by the book. Would somebody more experienced be so kind and point out where the problem could be?
Upvotes: 1
Views: 1692
Reputation: 4014
(*env)->SetIntField( env, cls, fid, state.fix);
This doesn't look right. You are trying to set an object instance field, but you are passing cls
instead of jstate
as the object to access. You should use the following instead:
(*env)->SetIntField( env, jstate, fid, state.fix);
Make the corresponding change for your other Set<type>Field
calls as well.
Upvotes: 2