Zannith
Zannith

Reputation: 439

How to call class method from JNI and cast the return to a custom class

First day working with JNI and in my search I have not found a solution that quite matches the problem I am having. I have three classes, and a class method I am trying use like this:

What my execution looked like in source code was:

Class1 class1Instance = new Class1();
// class1Instance.Method1() returns an EobjectClass which is cast to Class2
Class2 result = (Class2) class1Instance.Method1("Some string of text");

result then had the object I desired. I am struggling with how to do this from the JNI interface. Here is what I have so far.

jclass lookForClass(JNIEnv* env, char* name)
{
    jclass clazz = env->FindClass(name);

    if (!clazz) {
        printf("Unable to find class %s\n", name);
        exit(1);
    }

    printf("Class %s found\n", name);
    fflush(stdout);

    return clazz;
}
jobject invokeClassObj(JNIEnv* env, jclass classInDll) {
    jmethodID init;
    jobject result;
    init = env->GetMethodID(classInDll, "<init>", "()V");
    if (!init) {
        printf("Error: Could not find class Constructor\n");
        return;
    }
    result = env->NewObject(classInDll, init);
    if (!result) {
        printf("Error: failed to allocate an object\n");
        return;
    }
    return result;
}
jclass Parser = lookForClass(env, "com/Path/Parser");
jclass TextModel = lookForClass(env, "com/Path/TextModel");
jobject ParserInstance = invokeClassObj(env, Parser);
jmethodID parse = GetMethodID(Parser, "parse", "(Ljava/lang/String;)Lorg/Path/Eobject;");

Now here is where I lose what I am supposed to do. What it looks like logically to me is:

TextModel model = static_cast<TextModel> (ParserInstance.parse("some text here"));

But how would I execute that in this JNI environment? If there is any information or clarifications I missed please comment.

Upvotes: 1

Views: 3023

Answers (1)

Christophe
Christophe

Reputation: 73366

As your method returns an object, you may invoke it as follows:

jobject model = env->CallObjectMethod(ParserInstance, parse, env->NewStringUTF("some text here")); 

For a general tutorial on invoking methods and static methods from C++, you can look at this step-by-step CodeProject article.

For the different ways to call a method you may look in Oracle's JNI reference. You'll see that alternatively, you can also pass the parameters using an array or a var arg list.

For the different ways to construct a string object, you can look here. In the code above, I assumed your original string on the C++ side was UTF8 encoded.

Upvotes: 1

Related Questions