开发者

How do I use SetArrayRegion to map an array from a C struct to Java class array?

开发者 https://www.devze.com 2023-04-07 23:43 出处:网络
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 som开发者_开发技巧ewhere

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 som开发者_开发技巧ewhere. 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]?? 


}`


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.

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);

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消