【问题标题】:How to receive a set<String> returned by java method in C++ JNI, can we Convert jobject to set<String>?如何在 C++ JNI 中接收 java 方法返回的 set<String>,我们可以将 jobject 转换为 set<String> 吗?
【发布时间】:2017-11-17 09:13:36
【问题描述】:

我正在使用 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 但失败了。我可以直接在集合中捕获它吗?或者我可以将作业转换为集合吗?

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

【问题讨论】:

  • “抓住这个”是什么意思? Set 不是 jarray,而是 jobject。如果你想访问集合中的元素,你可以例如在 Java 代码中使用 toArray 以返回 String[] 而不是 Set&lt;String&gt;。如果由于某种原因您无法更改 Java 代码,您可以在 C++ 中执行相同的操作(GetObjectClassGetMethodIDCallObjectMethod 等)。
  • 我收到了jobject中的信息,你能告诉我怎么读吗? jobject 持有 Set. 类型的值
  • 您将使用我提到的函数来获取对Set 类的引用,您要调用的Set 中的方法的ID(例如toArray),然后您会调用那个方法。一旦你有了jobjectArray,你就会像往常一样处理它。这都是标准的 JNI 编程(请参阅 docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/…),因此不清楚您到底遇到了什么问题。

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


【解决方案1】:

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

我没有开箱即用的集合示例,但它与您可以在此处找到的代码非常相似:

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

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

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

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

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

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

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

你也可以看这里:

https://github.com/mkowsiak/jnicookbook/tree/master/recipes/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);

  }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-22
    • 2015-11-17
    • 2021-04-26
    • 2011-08-24
    • 1970-01-01
    • 1970-01-01
    • 2021-06-22
    相关资源
    最近更新 更多