views:

173

answers:

2

How can we new primitive types in JNI. I have a function that returns a jobject. It is possible to return jint, jchar, etc.

There is NewString, why not NewInteger, NewCharacter, NewDouble, etc. There is no autoboxing at JNI layer at the moment.

I can go with the NewObject call, but this will be too much overhead to create primitive types.

jobject NewInteger(JNIEnv* env, jint value)
{
    jclass cls = FindClass(env, "java/lang/Integer");
    jmethodID methodID = GetMethodID(env, cls, "<init>", "(I)V", false);
    return env->NewObject(cls, methodID, value);
}

I have wrapper functions to get Class and MethodID.

A: 

jint, jdouble, etc. are not jobjects. As you say, they're primitive variables. Just fill them in!

jint someInt = 1;
jdouble someDouble = 3.14159;

Re edit: I see, you want to return boxed types like Integer, Double, etc. Yeah, the wrapper function you posted is probably the way to go.

Chris Jester-Young
I know they are not jobject types. But is there a better way to create jobject other than going through NewObject route? JNI has NewString, but not other primitive types' NewXXX call.
Firat
@Firat: I have a "better" way, which is to call the `valueOf` method of the boxed type, but that's really just calling a factory method and is functionally no different from using `NewObject`. :-P
Chris Jester-Young
I was thinking it might be a better idea, however valueOf takes String as an argument. I would need to NewString, and call static function.
Firat
@Firat: No, there's `Integer.valueOf(int)`, `Double.valueOf(double)`, etc.; in fact, that's what gets used in auto-boxing. (Try it and see!)
Chris Jester-Young
If that works, I would need to profile and see which one performs faster. thanks
Firat
@Firat: Please do, but chances are, they're pretty similar (unless you're boxing small integers: values between -128 and 127 do not construct new instances, when you're using `Integer.valueOf(int)`).
Chris Jester-Young
valueOf is giving just a little bit better result. Not worth mentioning.
Firat
A: 

Why do you feel that this approach is "too much overhead"? If you want to return a boxed value (which is an object that holds a primitive, not a "primitive type") then you need to create that object.

One alternative is to call the valueOf() method on the wrapper type.

However, I think you're better off returning the actual primitive value, and letting it get boxed (if you need that) once it's on the Java side.


If you're worried about the overhead for the function/constructor lookup, then you should cache the method IDs. Unlike object pointers, they will not change (with some caveats re unloaded classes that don't apply to primitive wrappers). See item 10.7 here: http://java.sun.com/docs/books/jni/html/pitfalls.html

Anon
I think the OP is trying to implement an interface that requires the boxed object on return; short of changing the interface, you have no way to directly return the primitive.
Chris Jester-Young
The operation needs to return jobject type. It is similar to Map.put(key,value) that returns an Object if it exists with similar key. The overhead is everytime I would need to find class, get methodId. It is possible to cache them to improve it, however it would be nice if JNI interface had these functions.
Firat