如何在C ++ JNI中接收java方法返回的set <string>,我们可以将jobject转换为set <string>吗?

时间:2017-11-17 09:13:36

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

我使用JNI从C ++调用Java类的实例方法。 我的Java方法返回集,我需要在C ++中捕获它。有人可以帮忙吗?

我的Java方法如下所示。

@Override
public Set<String> getRealmRights() 
{
     Set<String> realmRights = new HashSet<>();
     -----------------
     -----------------
     return realmRights;
}

我正在调用C ++中的方法,如下所示。

jmethodID getRealmRightsMethodId = env->GetMethodID(keycloakAdapterApplicationClassId, "getRealmRights", "()Ljava/util/Set;");
if(getRealmRightsMethodId != nullptr)
{
    jobject rights = (jobject ) env->CallObjectMethod(keycloakAdapterApplication, getRealmRightsMethodId);
    //@ this stage I want to read the information from jobject,Please help?
}

我正确获取方法ID,甚至可以执行该方法。

我尝试在set中键入cast jobject但是失败了。我可以直接在集合中捕获它还是可以将jobject转换为set?

我想打印java函数返回的信息。请帮忙吗?

1 个答案:

答案 0 :(得分:1)

您必须访问Set类方法并检索存储在集合中的对象。

我没有开箱即用的套装样本,但它与您在此处可以找到的代码非常相似:

https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo037

您需要做的是使用SetGetMethodID对象获取方法,然后调用它们。

这样,您可以下降到Set内存储的数据。在您的情况下,您必须:

  • 调用方法GetMethodID(并将Set对象传递到其中)以从Iterator获取Set

https://docs.oracle.com/javase/7/docs/api/java/util/Set.html#iterator()

  • 为类GetMethodID的对象调用方法Iterator,这样您就可以获得两种方法:hasNextnext

  • 然后,您必须使用Iterator迭代Set并逐个检索元素(它们将是jobject类型)

你也可以看一下:

https://github.com/mkowsiak/jnicookbook/tree/master/recipeNo042

  /* Get objarg's class - objarg is the one we pass from
     Java */
  jclass clsSet = (*env)->GetObjectClass(env, objarg);

  /* Use javap to get propper descriptor
     > javap -s -p java.util.Set | grep -A 1 toArray
         public abstract java.lang.Object[] toArray();
           descriptor: ()[Ljava/lang/Object;
  */

  jmethodID midToArray =
    (*env)->GetMethodID(env, clsSet, "toArray", "()[Ljava/lang/Object;");

  /* We have to make sure that method exists */
  if (midToArray == NULL) {
    return -1; /* method not found */
  }

  /* Once we have method, we can call "toArray" and this way
     get array of all keys */
  jobjectArray arrayOfElements = (*env)->CallObjectMethod(env, objarg, midToArray);

  /* We will iterate over the array so we can get value for each key */
  int arraySize = (*env)->GetArrayLength(env, arrayOfElements);

  /* We want to go over all elements (all keys) */
  for (int i=0; i < arraySize; i++)
  {
    /* First, we need to get key value from array of all keys */
    jstring obj = (*env)->GetObjectArrayElement(env, arrayOfElements, i);
    const char* c_string = (*env)->GetStringUTFChars(env, obj, 0);

    /* We can print values passed to C from Java */
    printf("[value] = [%s]\n", c_string);

    /* Make sure to release local stuff */
    (*env)->ReleaseStringUTFChars(env, obj, c_string);

  }