如何使用 SetArrayRegion 将数组从 C 结构映射到 Java 类数组?
我想访问 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 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]??
}`
I want to access data members of a C struct(below) and map them onto an array in my java class. I have tried to used Set<>ArrayRegion to map the values but I am going wrong somewhere. Below is an example of what I am trying to do. Can somebody please help me with the correct syntax to map the values?
c header
`
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]??
}`
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
也许您需要首先分配数组。
这意味着使用 NewLongArray() 创建足够长度的数组对象,使用 SetLongArrayRegion() 填充数组对象,然后使用 SetObjectField() 将新数组实例设置为 java 对象(丢弃旧数组)。
您可以通过确保在调用 JNI 填充数组之前在 Java 中分配足够大的数组来快速测试该理论。
现在尝试您的 GetField、SetLongArrayRegion 想法。确保 num_states < 1000.
一旦您证明这一点可以开始工作,您就可以研究您希望 API 究竟如何工作。对此的想法:
保留当前设计,但让 JNI 分配数组。
创建一个新的 Java 对象“AA”,并让 JNI 为每个 C++“aa”设置一个并填充它,然后将 BB(又名 J)数组附加到 J 对象。 j.aa = new AA[num_states];
FWIW您正在尝试在C ++ / Java之间复制数据(不是映射,因为术语映射的使用意味着某种共享,更新一个不会更新另一个,除非您重新复制)
FWIW C / C ++中的“长”可能是32位在您的平台上,但 Java 上的“long”始终是 64 位。
Maybe you need to allocate the array to start with.
This means creating the array object with enough length NewLongArray(), using SetLongArrayRegion() to fill the array object, then using SetObjectField() to set the new array instance into java object (disarding the old one).
You can test this theory out quickly by ensuring in Java you allocate a big enough array before calling your JNI to fill it.
Now try your GetField, SetLongArrayRegion ideas. Making sure that num_states is < 1000.
Once you have proven this to start working, you can work on how exactly you want your API to work. Ideas on this:
Keep your current design, but have JNI allocate the array.
Create a new Java object "AA" and have JNI instate one for each C++ "aa" and fill it in, and then attach an array of BB (aka J) to the J object. j.aa = new AA[num_states];
FWIW you are trying to copy the data between C++/Java (not map, as use of term map implies some kind of sharing, updating one will not update the other unless you re-copy)
FWIW "long" in C/C++ maybe 32bit on your platform, but "long" on Java is always 64bit.