如何访问从C+;返回Java.lang.String的Java方法的返回值+;在JNI? 我试图从一个从C++调用的java方法中传递一个字符串。我无法确定应该调用什么JNI函数来访问该方法,并返回一个jstring值
我的代码如下: C++部分如何访问从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
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);