2

I have C code that call a kernel module and I want to pass a struct to it. This seems doable ex - char device catch multiple (int) ioctl-arguments

However I am invoking the c code through java JNI. It was said C struct mapping is to Java object. so am passing an object to the C native function.

Here is my JNI c function

  JNIEXPORT jint JNICALL Java_com_context_test_ModCallLib_reNice
  (JNIEnv *env, jclass clazz, jobject obj){

     // convert objcet to struct  
     // call module through IOCTL passing struct as the parameter
  }

How should I get a struct from obj?

EDIT: here is the object that I am passing,

class Nice{

    int[] pids;
    int niceVal;

    Nice(List<Integer> pID, int n){
        pids = new int[pID.size()];
        for (int i=0; i < pids.length; i++)
        {
            pids[i] = pID.get(i).intValue();
        }
        niceVal = n;
    }
}

the struct I want to have is this,

struct mesg {
     int pids[size_of_pids];
     int niceVal;
};

How should I approach?

Community
  • 1
  • 1
user340
  • 375
  • 12
  • 28

2 Answers2

1

You will need to use JNI methods to access the fields, for example:

//access field s in the object
jfieldID fid = (env)->GetFieldID(clazz, "s", "Ljava/lang/String;");
if (fid == NULL) {
    return; /* failed to find the field */
}

jstring jstr = (env)->GetObjectField(obj, fid);
jboolean iscopy;
const char *str = (env)->GetStringUTFChars(jstr, &iscopy);
if (str == NULL) {
    return; // usually this means out of memory
}

//use your string
...

(env)->ReleaseStringUTFChars(jstr, str);

...

//access integer field val in the object
jfieldID ifld = (env)->GetFieldID(clazz, "val", "I");
if (ifld == NULL) {
    return; /* failed to find the field */
}
jint ival = env->GetIntField(obj, ifld);
int value = (int)ival;

There are member functions in the JNIEnv class to do whatever you need: to read and modify member variables of the class, to invoke methods and even to create new classes. Have a look at the JNI Specifications for more details.

Aleks G
  • 56,435
  • 29
  • 168
  • 265
  • My object has an int array and an int how to do it then? – user340 Aug 24 '12 at 14:26
  • @kani I updated my answer to show how to get an integer field. Getting an array is not much more complicated. Go through the documentation - everything is in there. Please don't expect other to do it for you. – Aleks G Aug 24 '12 at 14:38
  • Thakz Aleks G :) now the example looks simple.. Will it be possible to map the object in to struct? (I mean without accessing objects fields) – user340 Aug 24 '12 at 14:48
  • 1
    @kani No, you cannot "map" the object to a struct. You can retrieve all fields and create a `struct` in C to make your life easier, yet you'll need to retrieve values of each field using JNI functions. – Aleks G Aug 24 '12 at 14:55
  • Yes and thankz. It looks like that too..http://stackoverflow.com/questions/4015121/jni-mapping-structure-in-java However I will have to have a int array inside the struct, which is of size of the objects array size. Which may change from time to time.. – user340 Aug 24 '12 at 15:17
  • How can I specify the size for the array inside the struct? – user340 Aug 24 '12 at 15:18
  • 1
    @kani You will need to use JNI function `GetArrayLength` to determine the length of the array; then you can use the result when declaring your struct. – Aleks G Aug 24 '12 at 15:27
  • jfieldID ifld2 = (env)->GetIntArrayElements(clazz, "pids", NULL); This is wrong ryt? I have the array inside the object how to get around this? – user340 Aug 24 '12 at 16:17
0

You have to manually copy the fields from the object. You can call JNI methods to get the value of the fields by name. It might be easier to pass the fields themselves into the method instead of passing an object.

Samuel
  • 16,923
  • 6
  • 62
  • 75