如何在JNI中访问从C ++返回java.lang.String的Java方法的返回值?

我试图从一个从C ++调用的Java方法传回一个字符串。 我无法找出我应该调用什么JNI函数来访问该方法并返回一个jstring值。

我的代码如下:

C ++部分

main() { jclass cls; jmethodID mid; jstring rv; /** ... omitted code ... */ cls = env->FindClass("ClassifierWrapper"); mid = env->GetMethodID(cls, "getString","()Ljava/lang/String"); rv = env->CallStaticMethod(cls, mid, 0); const char *strReturn = env->GetStringUTFChars(env, rv, 0); env->ReleaseStringUTFChars(rv, strReturn); } 

Java代码

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

方法签名 (来自“javap -s Class”)

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

你应该有

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

然后,您需要调用构造函数来获取新对象:

 jmethodID classifierConstructor = env->GetMethodID(cls,"", "()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); 

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

Java方面

 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,"", "()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); 

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

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

要调用返回Object(例如String)的方法,可以调用CallStaticObjectMethod()。 这将返回对该方法返回的String的jobject本地引用。 您可以安全地将jobject转换为jstring(请参阅http://java.sun.com/docs/books/jni/html/types.html )并使用GetStringUTFChars检索字符和GetStringUTFLength以获取字符数。

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

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

祝好运

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