如何访问从C+;返回Java.lang.String的Java方法的返回值+;在JNI? 我试图从一个从C++调用的java方法中传递一个字符串。我无法确定应该调用什么JNI函数来访问该方法,并返回一个jstring值

如何访问从C+;返回Java.lang.String的Java方法的返回值+;在JNI? 我试图从一个从C++调用的java方法中传递一个字符串。我无法确定应该调用什么JNI函数来访问该方法,并返回一个jstring值,java,c++,java-native-interface,Java,C++,Java Native Interface,我的代码如下: C++部分 main() { jclass cls; jmethodID mid; jstring rv; /** ... omitted code ... */ cls = env->FindClass("ClassifierWrapper"); mid = env->GetMethodID(cls, "getString","()Ljava/lang/String"); rv = env->CallSta

我的代码如下:

C++部分

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);
}
方法签名(来自“javap-s类”)


第一个问题是ClassifierRapper.getString()不是静态的。您需要将其设置为静态或实例化ClassifierRapper

第二个问题是使用GetMethodId而不是GetStaticMethodId

要调用返回对象(如字符串)的方法,可以调用CallStaticObjectMethod()。它将返回对该方法返回的字符串的jobject本地引用。您可以安全地将jobject强制转换为jstring(请参阅),并使用GetStringUTFChars检索字符,使用GetStringUTFLength获取字符数

JNI非常棘手。您需要检查所有的错误代码(如果没有错误代码,请使用ExceptionCheck()。如果不检查错误,它在大多数情况下都会无声地失败,通常不会出现在实际的错误所在的位置

您还需要了解本地引用和全局引用之间的差异(以及生成新引用的方法),以避免内存泄漏和引用限制。例如,FindClass返回对类对象的本地引用,但GetMethodId返回MethodID

祝你好运

cls = env->FindClass("ClassifierWrapper"); 
然后需要调用构造函数以获取新对象:

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

jobject classifierObj = env->NewObject( cls, classifierConstructor);
现在调用该方法:

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

签名
()Ljava/lang/String
是错误的,因为进入JVM的类名必须以
结尾
,那么在这种情况下签名必须是
()Ljava/lang/String

完整的工作解决方案如下:

Java端

本土

jclass-cls;
jmethodidemid;
jstring rv;
cls=jniEnv->FindClass(“分类器说话者”)//PLASE还将包名视为包\No.\类名
jmethodID classifierConstructor=jniEnv->GetMethodID(cls,“,”()V”);
if(classifierConstructor==NULL){
返回NULL;/*引发异常*/
}
jobject ClassifierRobj=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);
JNINEV->释放StringUTFChars(rv、strReturn);

类名应以结尾;比如:()Ljava/lang/String;无法使用类型为“jobject”(aka“\u jobject*”)的右值初始化类型为“jstring”(aka“\u jstring*)的变量jstring jMacAddr=env->CallObjectMethod(producsdescription,仅jobject-to-jstring,如下所示:rv=(jstring)(env->CallObjectMethod(classifierbj,getStringMethod,0));
jmethodID classifierConstructor = env->GetMethodID(cls,"<init>", "()V"); 
if (classifierConstructor == NULL) {
  return NULL; /* exception thrown */
}

jobject classifierObj = env->NewObject( cls, classifierConstructor);
jmethodID getStringMethod = env->GetMethodID(cls, "getString", "()Ljava/lang/String;"); 
rv = env->CallObjectMethod(classifierObj, getStringMethod, 0); 
const char *strReturn = env->GetStringUTFChars(env, rv, 0);
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);