Java JNI:如何从 C++ 的本机方法设置 Java 类的 String [] 字段

Posted

技术标签:

【中文标题】Java JNI:如何从 C++ 的本机方法设置 Java 类的 String [] 字段【英文标题】:Java JNI: How to set String [ ] field Of Java class from native method of C++ 【发布时间】:2016-11-10 09:59:21 【问题描述】:

我有这个课程:ProcessSolution

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

我想从我的本地方法中设置它的一个字段processSolutionSteps

这里是step_nameprocessSolutionSteps

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

    



我的问题是如何从上面的 c++ 方法中设置processSolutionSteps []

谢谢

【问题讨论】:

【参考方案1】:
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);

【讨论】:

我试过了,但我得到了ArrayIndexOutOfBoundException:4, 我正在使用 DDD(Data Display Debugger) 进行调试,循环工作正常,如何检查 String Array 是否设置为对象? 你需要return arrPS;Java_nativeclass_Jmain_getProcessSolutions()的末尾。 我最后有return arrPS,如果我评论这个填充String [ ]的代码,我在java端用其他值正确地得到arrPs谢谢..

以上是关于Java JNI:如何从 C++ 的本机方法设置 Java 类的 String [] 字段的主要内容,如果未能解决你的问题,请参考以下文章

如何跟踪从Java到C的JNI方法?

无法从 JNI 设置 Java int 数组字段

如何使用 JNI 从 JAVA 调用带有 C++ 参数的函数?

jbyte* 作为 JNI 中本机 C++ 方法的 ByteBuffer

如何使用 JNI 从本机 c 库将 double 和 unsigned int 返回到 java

JNI将参数传递给c ++的方法