从C代码中设置/获取Java List<>

8

Java 代码

在 Java 代码中,我有一个名为 IdentificationResult 的类,该类有 3 个成员:

  1. enrollmentID
  2. enrollmentSettings
  3. identParams

以下是该类:

package com.vito.android.framework.service;

class IdentificationResult
{
    class IdentParams {
        byte[] otp;
        String seedId;
    }

    String enrollmentID;
    String enrollmentSettings;
    List<IdentParams> identParams;
}

在主类中,我有一个名为GetAuthenticationStatus() 的函数,这是主类:

public class TokenManager 
{
    /* Some code goes here ... */

    public IdentificationResult GetAuthenticationStatus( )
    {
        /* Function do some actions here ... */
        return new IdentificationResult;
    }
}

C++ 代码

我以这种方式从C++代码中调用Java方法

void GetAuthenticationStatus( )
{
    // Attach current thread.
    JNIEnv *env = NULL;
    m_javaVM->AttachCurrentThread( env, NULL );
    if( env == NULL ) {
        return -1;
    }

    jclass clazz = NULL;
    clazz = env->GetObjectClass( m_classObject );
    if( clazz == NULL ) {
        return -1;
    }

    // Get class method.
    jmethodID clazzMethod = NULL; 
    env->GetMethodID( clazz, "GetAuthenticationStatus", "(V;)Lcom/vito/android/framework/service/IdentificationResult;" );
    if( clazzMethod == NULL ) {
        return VCS_RESULT_ERROR;
    }

    // Call Java 'GetAuthenticationStatus' function.
    jobject methodReturnObj = env->CallObjectMethod( m_classObject, clazzMethod );

    // Get IdentificationResult Class from Object.
    jclass identifyResultClass = env->GetObjectClass( methodReturnObj );
    if( identifyResultClass == NULL ) 
    {
        return -1;
    }

    // Get identParams.
    jfieldID fieldID = env->GetFieldID( identifyResultClass , "identParams", "***1. Question***");
    if( fieldID == NULL ) {
        return -1;
    }
    else
    {
        *** 2. Question *** 
    }

}

问题

  1. 我需要在这里写什么才能获得 List<IdentParams> 字段的ID?

  2. 我该如何获取或设置字段的值?


@JoopEggen 你能提供一些示例代码吗? - Viktor Apoyan
1
我开始打字了,但实际上您已经使用了所需的一切。您可以访问字段或创建一个getter getIdentParams。抱歉,但JNI是一种可怕的冗长编码方式。http://download.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html - Joop Eggen
2个回答

12

好的,我已经解决了问题并想与您分享结果,以下是解决方案:

    fieldID = env->GetFieldID( identifyResultClass , "identParams", "Ljava/util/List;" );
    if( fieldID != NULL ) 
    {
        // Find "java/util/List" Class (Standard JAVA Class).
        jclass listClass = env->FindClass( "java/util/List" );
        if( listClass == NULL ) {
            DBG_WARNING(DBG_CTX, ("Can't Find Class \"java/util/List\".\n"));
            return -1;
        }

        // Get List object field.
        jobject listObject = env->GetObjectField( methodReturnObj, fieldID );
        if( listObject == NULL ) {
            DBG_WARNING(DBG_CTX, ("Can't get ObjectField for \"List\".\n"));
            return -1;
        }

        // Get "java.util.List.get(int location)" MethodID
        jmethodID getMethodID = env->GetMethodID( listClass, "get", "(I)Ljava/lang/Object;" );
        if( getMethodID == NULL ) {
            DBG_WARNING(DBG_CTX, ("Can't get MethodID for \"java.util.List.get(int location)\".\n"));
            return -1;
        }

        // Get "int java.util.List.size()" MethodID
        jmethodID sizeMethodID = env->GetMethodID( listClass, "size", "()I" );
        if( sizeMethodID == NULL ) {
            DBG_WARNING(DBG_CTX, ("Can't get MethodID for \"int java.util.List.size()\".\n"));
            return -1;
        }

        // Call "int java.util.List.size()" method and get count of items in the list.
        int listItemsCount = (int)env->CallIntMethod( listObject, sizeMethodID );
        DBG_DISPLAY(DBG_CTX,("List has %i items\n", listItemsCount));

        for( int i=0; i<listItemsCount; ++i )
        {
            // Call "java.util.List.get" method and get IdentParams object by index.
            jobject identParamsObject = env->CallObjectMethod( listObject, getMethodID, i - 1 );
            if( identParamsObject == NULL )
            {
                DBG_WARNING(DBG_CTX, ("Can't get Object from \"identParamsObject\" at index %i.\n", i - 1));
            }


        }

感谢@Joop Eggen,他给了我很好的想法!!!

2

以下代码不能编译通过,但你可以理解其含义:

jobject list = env->GetObjectField(methodReturnObj, "identParams"); // java.util.List
getMID = env->GetMethodID (listClass, "get","(I)Object");
jobject someIdentParam = env->CallMethod(getMid, new Object[] { list, 0 }); // java.lang.Object

首先阅读文档。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接