Как получить доступ к возвращаемому значению метода Java, возвращающего java.lang.String из C ++ в JNI? - PullRequest
4 голосов
/ 03 августа 2010

Я пытаюсь вернуть строку из метода Java, вызванного из C ++.Я не могу выяснить, какую функцию JNI следует вызвать для доступа к методу и получить значение jstring.

Мой код выглядит следующим образом:

C ++ part

main() {
    jclass cls;
    jmethodID mid;
    jstring rv;

/** ... omitted code ... */

    cls = env->FindClass("ClassifierWrapper");
    mid = env->GetMethodID(cls, "getString","()Ljava/lang/String");

    rv = env->CallStatic<TYPE>Method(cls, mid, 0);
    const char *strReturn = env->GetStringUTFChars(env, rv, 0);

    env->ReleaseStringUTFChars(rv, strReturn);
}

Java Code

public class ClassifierWrapper {
    public String getString() { return "TEST";}
}

Подпись метода (из "класса javap -s")

public java.lang.String getString();
  Signature: ()Ljava/lang/String;

Ответы [ 4 ]

8 голосов
/ 03 августа 2010

Вы должны иметь

cls = env->FindClass("ClassifierWrapper"); 

Затем вам нужно вызвать конструктор, чтобы получить новый объект:

jmethodID classifierConstructor = env->GetMethodID(cls,"<init>", "()V"); 
if (classifierConstructor == NULL) {
  return NULL; /* exception thrown */
}

jobject classifierObj = env->NewObject( cls, classifierConstructor);

Вы получаете статический метод (даже если имя метода неверно). Но вам нужно получить метод экземпляра, так как getString () не является статическим.

jmethodID getStringMethod = env->GetMethodID(cls, "getString", "()Ljava/lang/String"); 

Теперь вызовите метод:

rv = env->CallObjectMethod(classifierObj, getStringMethod, 0); 
const char *strReturn = env->GetStringUTFChars(env, rv, 0);
2 голосов
/ 06 декабря 2016

Полное рабочее решение приведено ниже:

Java Side

public class ClassifierWrapper {
public ClassifierWrapper(){}
public String getString() { return "TEST";}
}

Собственная сторона

jclass cls;
jmethodID mid;
jstring rv;


cls = jniEnv->FindClass("ClassifierWrapper"); //plase also consider your package name as package\name\classname

jmethodID classifierConstructor = jniEnv->GetMethodID(cls,"<init>", "()V");
if (classifierConstructor == NULL) {
    return NULL; /* exception thrown */
}
jobject classifierObj = jniEnv->NewObject( cls, classifierConstructor);

jmethodID getStringMethod = jniEnv->GetMethodID(cls, "getString", "()Ljava/lang/String;");

rv = (jstring)(jniEnv->CallObjectMethod(classifierObj, getStringMethod));
const char *strReturn = jniEnv->GetStringUTFChars( rv, 0);


jniEnv->ReleaseStringUTFChars(rv, strReturn);
1 голос
/ 03 августа 2010

Первая проблема заключается в том, что ClassifierWrapper.getString () не является статическим.Вам нужно будет сделать его статическим или создать экземпляр ClassifierWrapper.

Вторая проблема заключается в том, что вы используете GetMethodId вместо GetStaticMethodId.

Для вызова метода, возвращающего объект (например, String).Вы бы вызвали CallStaticObjectMethod ().Это вернет локальную ссылку на объект задания на строку, возвращенную методом.Вы можете безопасно преобразовать задание в jstring (см. http://java.sun.com/docs/books/jni/html/types.html) и использовать GetStringUTFChars для получения символов, а GetStringUTFLength для получения количества символов.

JNI очень сложно. Вам нужно проверить ошибкукод для всего (используйте ExceptionCheck (), когда нет кода ошибки). Если вы не проверяете ошибки, он в большинстве случаев завершается сбоем молча, и обычно не в точке, где находится настоящая ошибка.

Вытакже необходимо понимать разницу между локальными и глобальными ссылками (и какие методы генерируют новые ссылки), чтобы не пропускать память и не выходить за пределы ссылки.Например, FindClass возвращает локальную ссылку на объект класса, но GetMethodId возвращает MethodID.

Удачи

0 голосов
/ 21 февраля 2013

Подпись ()Ljava/lang/String неверна, поскольку имя класса в JVM должно заканчиваться ;, тогда в этом случае подпись должна быть ()Ljava/lang/String;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...