0

I have a code something similar to this

struct time { long milliscnds; int secs; } 

In my java file , I had something like this

class jtime { long millscnds; int secs; } 

new jtime time = new jtime();

public int native getTimeFromC(object time);

in native class

getTimeFromc(JNIEnv* env, jobject thiz,jobject jtime) { struct time *mytime = getTime(); now to fill the jtime with mytime } 

Suggestions please?

2 Answers 2

1

You can simplify your Java class and the required JNI code.

Currently, your native method has some issues:

public int native getTimeFromC(object time); 
  1. Parameter is Object but should be jtime.
  2. Return value doesn't seem to have a purpose.
  3. Since the method completely initializes a jtime object, why not create and return a jtime object?

This class definition has a factory method to create the object and a constructor that moves some the initialization work over from the JNI side.

public class jtime { long millscnds; int secs; public jtime(long millscnds, int secs) { this.millscnds = millscnds; this.secs = secs; } public native static jtime FromC(); } 

The factory method can be implemented like this:

JNIEXPORT jobject JNICALL Java_jtime_FromC (JNIEnv * env, jclass clazz) { struct time *mytime = getTime(); jmethodID ctor = (*env)->GetMethodID(env, clazz, "<init>", "(JI)V"); jobject obj = (*env)->NewObject(env, clazz, ctor, mytime->milliscnds, mytime->secs); return obj; } 

Tip: The javap tool is like javah but shows the signatures of non-native methods. Using javap -s jtime, you can see the signature of the constructor.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer , i am intentionally returning int which sends me the result which i need in future
0

Something like the following:

void getTimeFromc(JNIEnv* env, jobject thiz, jobject jtime) { struct time *mytime = getTime(); // now to fill the jtime with mytime jclass jtimeClazz = (*env)->GetObjectClass(jtime); // Get the class for the jtime object // get the field IDs for the two instance fields jfieldID millscndsFieldId = (*env)->GetFieldID(jtimeClazz, "milliscnds", "J"); // 'J' is the JNI type signature for long jfieldID secsFieldId = (*env)->GetFieldID(jtimeClazz, "secs", "I"); // 'I' is the JNI type signature for int // set the fields (*env)->SetLongField(jtime, millscndsFieldId, (jlong)mytime.milliscnds); (*env)->SetIntField(jtime, secsFieldId, (jint)mytime.secs); } 

Ideally you should cache the values of millscndsFieldId and secsFieldId as they won't change during execution (and you could also cache jtimeClazz if you NewGlobalRef it).

All JNI functions are documented here: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html

2 Comments

Thank you very much , i have a doubt , can i free the struct after setting the java members ...?
Yep, there is no shared memory here - you're copying the values

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.