如何从JNI调用类方法并将返回值转换为自定义类

时间:2017-06-23 18:56:01

标签: java c++ java-native-interface

与JNI合作的第一天,在我的搜索中,我找不到与我遇到的问题完全匹配的解决方案。我有三个类,我尝试使用类方法:

  • // THIS IS A BIDDING PROCESS var progressBar = $("#progressBar"); var scenario = 3 var width = 265; var processDuration = 60000; var processDelay = 3000; var time_per_scenario = (processDuration / scenario); var width_per_processDelay = (width / (processDuration / processDelay)); // Call the animateProgressBar for first time animation; animateProgressBar(); setInterval(function(){ if(scenario != 0) { if(time_per_scenario != 0) { time_per_scenario -= 1000; width -= width_per_processDelay; } else { scenario--; width = 265; time_per_scenario = 20000; animateProgressBar(); } } else { scenario = 3; } }, processDelay); function animateProgressBar() { progressBar.attr("style", "width: " + width); console.log("animateProgressBar Again with scenario: " + scenario); if(scenario == 0 ) { progressBar .velocity({ width: width}, { duration: 1 }) .velocity({ width: 0 }, { duration: time_per_scenario }) .velocity({ width: width }, { duration: 1 }) .velocity({ width: 0 }, { duration: time_per_scenario, }) .velocity({ width: width}, { duration: 1 }) .velocity({ width: 0 }, { duration: time_per_scenario, }); } else if(scenario == 1 ){ progressBar .velocity({ width: width }, { duration: 1 }) .velocity({ width: 0 }, { duration: time_per_scenario, }) .velocity({ width: width}, { duration: 1 }) .velocity({ width: 0 }, { duration: time_per_scenario, }); } else { progressBar .velocity({ width: width }, { duration: 1 }) .velocity({ width: 0 }, { duration: time_per_scenario }); } };
    • Class1
  • EobjectClass Method1("some text")
  • Class2

我在源代码中的执行情况是:

EobjectClass

Class1 class1Instance = new Class1(); // class1Instance.Method1() returns an EobjectClass which is cast to Class2 Class2 result = (Class2) class1Instance.Method1("Some string of text"); 然后有了我想要的对象。我正在努力从JNI界面如何做到这一点。这是我到目前为止所拥有的。

result

现在,我失去了我应该做的事情。逻辑上对我来说是:

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;");

但是我如何在这个JNI环境中执行它?如果有任何信息或说明我错过了请评论。

1 个答案:

答案 0 :(得分:1)

当您的方法返回一个对象时,您可以按如下方式调用它:

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

有关从C ++调用方法和静态方法的一般教程,您可以查看此step-by-step CodeProject article

有关调用方法的不同方法,您可以查看Oracle's JNI reference。您还可以看到,您也可以使用数组或var arg列表传递参数。

对于构造字符串对象的不同方法,您可以look here。在上面的代码中,我假设您在C ++端的原始字符串是UTF8编码。