Since Point is an inner class, the way to get it would be

jclass cls = (*env)->FindClass(env, "com/example/ndktest/NDKTest$Point");

The $ convention for inner classes is not really clearly documented in the authoritative specs, but is entrenched in so much working code that it's unlikely to change. Still, it would feel somewhat more robust if you restricted your JNI code to work with top-level classes.

You want a constructor that takes two ints as arguments. The signature for that is (II)V, so:

constructor = (*env)->GetMethodID(env, cls, "<init>", "(II)V");

Next time, include some error handling in your code, such that you'll have a clue which part of it doesn't work!


The specification is correct, but a bit misleading in this case. GetMethodID requires a method name and a method signature. The specification says:

To obtain the method ID of a constructor, supply <init> as the method name and void (V) as the return type.

Note that it says return type, not signature. Although void(V) looks superficially similar to a signature, the specification is telling you that the signature must specify a void (that is, V) return type.

The correct signature for a no-argument constructor is ()V. If the constructor has arguments, they should be described between the parentheses, as other commenters have noted.


Some problems with your code.

First, why are you creating your own Point class rather than using library-provided android.graphics.Point?

Second, the class spec for nested classes is different - it would be "com/example/ndktest/NDKTest$Point". Class nesting is different from packages.

Third, I don't think JNI lets you create instances of nonstatic nested classes. You need to pass the nesting class object' this pointer at object creation - there's no such argument.

Finally, while I've seen the guidance to use "void(V)" as a constructor method signature, but this is out of line with the rest of method signatures; normally, a method with two int parameters and void return type would be "(II)V".

As a side note, I found it much cleaner to pass primitive types and arrays of primitive typed from NDK to Java. Object creation/access is messy and hard to debug.


In JNI you can always use the javap tool for finding method signatures. Just run javap -s com.example.ndktest.NDKTest and copy the method signatures from the output.


Three steps should create the Point object with JNI:

jobject
Java_com_example_ndktest_NDKTest_ImageRef(JNIEnv* env, jobject obj, jint width, jint height, jbyteArray myArray)
{
    ...
    jclass cls = (*env)->FindClass(env, "com/example/ndktest/NDKTest$Point");
    jmethodID constructor = (*env)->GetMethodID(env, cls, "<init>", "void(V)");
    jobject object = (*env)->NewObject(env, cls, constructor, obj, 5, 6);
    ...
}