1

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:

  • Class1
    • EobjectClass Method1("some text")
  • Class2
  • EobjectClass

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.

1 Answer 1

1

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.

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

11 Comments

I don't know if it makes a difference but my method returns an interface Eobject, which I am then casting to textmodel. When I execute the line above with valid text my model is resulting in null, when it should be a structured tree.
But if you receive an object from java, it's be a jobject containing a reference to the real object. Have you checked that the returend object is ok before your case ? For example using env->GetObjectClass(env, model); and looking at the name of that class ? Second question do you use your object immediately, or do you keep it, do a lot of stuff and use it later (because in this case i could have been dereferenced unless you locked it) ?
Neither my class or my object are returning NULL which I assumed meant it was working okay. I am not sure how to get the actual name of the class from the GetObjectClass function as it returns a memory location. And yes i use the object immediately. on invokeclassobject function I call its constructor which does a short initialization, I then immediately call the parse method on that.
-update, I am now getting an Access violation reading location 0x00A20004 within the NewStringUTF function.
The newStringUTF expects a char* pointer to a valid UTF C-string which is null terminated. It may trhow if out of memory. It may also return NULL if it didn't work. May be first do a jstring x= .... to check that evrything went fien at this stage.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.