Search code examples
javac++cjava-native-interfacenative

Java JNI: How to set String [ ] field Of Java class from native method of C++


I have this class : ProcessSolution

public class ProcessSolution {
    private String processId;
    private String processName;
    private String processSolutionSteps [];
    private String processRemark;
    private String processNote;
}

And I want to set one of its field processSolutionSteps from my native method ,

Here step_name nothing but processSolutionSteps

JNIEXPORT jobjectArray JNICALL Java_nativeclass_Jmain_getProcessSolutions
  (JNIEnv *env, jobject jobject) {
    clientlist *cl = new clientlist();
    jmp_buf jmpb;
    int i, j , k;
    int listCount = 0, steps = 0;
    jobjectArray arrPS = NULL;
    jobject clsObj;
    struct process *list = NULL;
    struct procdtl *pdtl;
    char *remark, *note, *step_name;

    list = (struct process *)calloc (sizeof(process)  , 1);
    pdtl = (struct procdtl *)calloc (sizeof(procdtl)  , 1);
    remark = (char*) calloc(201 ,1);
    note = (char*) calloc(201 ,1);
    step_name = (char*) calloc(201 ,1);

    cl->get_proc_list ( &listCount, &list );

    jclass clsPS = env->FindClass("POJO/ProcessSolution");
    if( clsPS == NULL )
        return NULL;
    if( ( arrPS = env->NewObjectArray( listCount, clsPS, NULL ) ) == NULL );
        longjmp(jmpb,-1);
    for ( i = 0; i < listCount; ++i ) {
            remark = get_proc_remark (list[i].proc_id);
            note = get_proc_note (list[i].proc_id);
            get_proc_list (list[i].proc_id ,  &steps, &pdtl);

            for (j = 0; j < steps; j++) {
                memset(step_name, ' ', 200);
                strcpy(step_name, pdtl[j].desc[0]);
                if (data_in(ps.desc[1]))
                    sprintf(step_name+strlen(step_name), "%s", pdtl[j].desc[1]);
                if (data_in(ps.desc[2]))
                    sprintf(step_name+strlen(step_name), "%s", pdtl[j].desc[2]);
                if (data_in(ps.desc[3]))
                    sprintf(step_name+strlen(step_name), "%s",pdtl[j].desc[3]);
                if (data_in(ps.desc[4]))
                    sprintf(step_name+strlen(step_name), "%s", pdtl[j].desc[4]); 
            }

    }


}

My question is how do I set processSolutionSteps [] from above c++ method ?

Thank you


Solution

  • jfieldID procSolStepsID = env->GetFieldID(clsPS, "processSolutionSteps", "[Ljava/lang/String;");
    jclass clsStr = env->FindClass("java/lang/String");
    for (i = 0; i < listCount; ++i) {
        jobject procSolObj = env->NewObject(clsPS, env->GetMethodID(clsPS, "<init>", "()V"));
        jobjectArray solSteps = env->NewObjectArray(steps, clsStr, NULL);
        for (j = 0; j < steps; ++j) {
            // prepare step_name
            env->SetObjectArrayElement(solSteps, j, env->NewStringUTF(step_name));
        }
        env->SetObjectField(procSolObj, procSolStepsID, solSteps);
        env->SetObjectArrayElement(arrPS, i, procSolObj);
    }