JNI new primitive types
Asked Answered
K

2

5

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.

Kilian answered 22/3, 2010 at 21:6 Comment(2)
@Kilian - if you are getting to the point of worrying about this sort of thing, this is a sign that your application has too much JNI.Steeplejack
Our Java API uses the C code. Everything relies on the performance of the JNI calls. That's why I am doing best to make that part as quick as possible.Kilian
G
7

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.

Goulet answered 22/3, 2010 at 21:23 Comment(7)
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.Kilian
@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. :-PGoulet
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.Kilian
@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!)Goulet
If that works, I would need to profile and see which one performs faster. thanksKilian
@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)).Goulet
valueOf is giving just a little bit better result. Not worth mentioning.Kilian
R
1

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

Ronnyronsard answered 22/3, 2010 at 21:31 Comment(2)
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.Goulet
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.Kilian

© 2022 - 2024 — McMap. All rights reserved.