我想访问C结构的数据成员(下面)并将它们映射到我的java类中的数组。我曾尝试使用Set<> ArrayRegion来映射值,但我在某处出错了。以下是我想要做的一个例子。有人可以帮助我使用正确的语法来映射值吗?
c标题
`
typedef struct a {
long nls;
uint8_t *lane;
long t;
} aa;
typedef struct b {
uint32_t id;
uint64_t timestamp_ms;
long num_states;
aa *move_states;
} bb;
java class
class J {
int i_id;
long timestamp_ms;
long num_states;
long[] nls;
long[][] lane;
long[] t;
}
test.c的
JNIEXPORT jint JNICALL Java_com_android_...
(JNIEnv *env, jclass c, jobject obj)
{
bb c_struct;
// do some operations on c_struct to populate the structure
....
J java_class;
jFieldID fid;
jclass cls = (*env)->GetObjectClass(env,obj);
fid=(*env)->GetFieldID(env,cls,"i_id","I");
(*env)->SetIntField(env,obj,fid,c_struct.id);
... similar for timestamp_ms,num_states
// how do I map c_struct->move_states[i].nls to java_class.nls[i] ??
// also how do I map c_struct->move_states[i].lane[j] to java_class.lane[i][j]??
}`
答案 0 :(得分:0)
也许你需要分配数组来开始。
这意味着使用足够长度的NewLongArray()创建数组对象,使用SetLongArrayRegion()填充数组对象,然后使用SetObjectField()将新数组实例设置为java对象(丢弃旧对象)。
你可以通过在Java中确保在调用JNI来填充它之前分配足够大的数组来快速测试这个理论。
int SIZE = 1000; // make this big enough
J j = new J();
j.nls = new long[SIZE];
j.lane = new long[SIZE][SIZE]; // something like this multi-dimention array
j.t = new long[SIZE];
int i = callMyJniMethod(j);
现在尝试一下GetField,SetLongArrayRegion的想法。确保num_states是< 1000。
一旦您证明这一点开始工作,您就可以确定您希望API的运行方式。想法:
保留当前的设计,但让JNI分配数组。
创建一个新的Java对象“AA”并让JNI为每个C ++“aa”设置一个并填充它,然后将一个BB(又称J)数组附加到J对象。 j.aa =新AA [num_states];
FWIW你试图在C ++ / Java之间复制数据(不是map,因为使用术语映射意味着某种共享,更新一个不会更新另一个除非你重新复制)
C / C ++中的FWIW“long”在您的平台上可能是32位,但Java上的“long”总是64位。