![](/img/trans.png)
[英]What does the difference of the JNI method CallObjectMethod,CallObjectMethodV and CallObjectMethodA?
[英]CallObjectMethod does not return a string
我的目標是在C++
創建一個Java
類實例,然后調用Java
類中定義的方法。
以下是我的Java
類的摘要:
EXICodec.java
public class EXICodec {
...
private static String inputXML;
...
public EXICodec()
{
System.out.println("Constructor");
this.inputXML = "string";
...
}
...
public static void setInputXML(String inXML)
{
inputXML = inXML;
}
...
public static String getInputXML()
{
return inputXML;
}
以下是用於與該類交互的C++
代碼的摘要:
JavaInterface.hh
class JavaInterface
{
private:
JNIEnv* JNIEnvironment;
JavaVM* javaVM;
jclass javaClass;
jobject javaClassInstance;
jmethodID IDconstructor;
jmethodID IDsetInputXML;
jmethodID IDgetInputXML;
public:
JavaInterface();
void init_context( void);
void init_class( void);
void init_methods( void);
void setInputXML( std::string);
std::string getInputXML( void);
}
JavaInterface.cc
void JavaInterface::init_context(){..} //initiate the JNIEnvironment & javaVM attributes
void JavaInterface::init_class(){..} //initiate the javaClass attribute
void JavaInterface::init_methods()
{
this->IDconstructor = this->JNIEnvironment->GetMethodID(this->javaClass, "<init>", "()V");
if (this->IDconstructor == NULL)
{
throw std::runtime_error("JAVA_INIT_METHOD_EXCEPTION");
}
this->IDsetInputXML = this->JNIEnvironment->GetStaticMethodID(this->javaClass, "setInputXML", "(Ljava/lang/String;)V");
if (this->IDsetInputXML == NULL)
{
throw std::runtime_error("JAVA_INIT_METHOD_EXCEPTION");
}
this->IDgetInputXML = this->JNIEnvironment->GetStaticMethodID(this->javaClass, "getInputXML", "()Ljava/lang/String;");
if (this->IDgetInputXML == NULL)
{
throw std::runtime_error("JAVA_INIT_METHOD_EXCEPTION");
}
}
void JavaInterface::j_constructor()
{
this->javaClassInstance = this->JNIEnvironment->NewObject(this->javaClass, this->IDconstructor);
if (this->javaClassInstance == NULL)
{
throw std::runtime_error("JAVA_CONSTRUCTOR_CALL_EXCEPTION");
}
}
void JavaInterface::j_setInputXML( std::string str)
{
jstring argument = this->JNIEnvironment->NewStringUTF(str.c_str());
this->JNIEnvironment->CallVoidMethod(this->javaClassInstance, this->IDsetInputXML, argument);
}
std::string JavaInterface::j_getInputXML()
{
jstring javaString = NULL;
// ---> PROBLEM HERE : javaString is still NULL after the line below : <---
javaString = (jstring)this->JNIEnvironment->CallObjectMethod(this->javaClassInstance, this->IDgetInputXML, 0);
// jString to char*
const char *nativeString = this->JNIEnvironment->GetStringUTFChars(javaString, JNI_FALSE);
// char* to std::string
std::string str(nativeString);
this->JNIEnvironment->ReleaseStringUTFChars(javaString, nativeString);
return str;
}
所以我的問題是CallObjectMethod
的調用不會返回任何內容。 我試圖將Java方法更改為static
但它沒有改變。
更一般地說,如何將字符串從Java
返回到C++
? 也許我的開始想法很糟糕。
所以,抱歉這么長時間,但我解決了問題。 基本上,它是一個小錯字導致破壞(至少在你的MWE):
this->IDgetString = this->JNIEnvironment->GetStaticMethodID(this->javaClass
, "getString"
, "(()Ljava/lang/String;");
// ^ This parenthesis must be removed.
此外,我注意到你沒有初始化對象。 我重新編寫代碼以使用instace方法而不是靜態方法,對我來說,MWE運行正常。
這是我使用的EXICodec.java
的代碼, 這里是JavaInterface.cpp
的代碼。
我再次看了你原始代碼,發現了別的東西。
void JavaInterface::init_methods()
{
this->IDconstructor = this->JNIEnvironment->GetMethodID(this->javaClass, "<init>", "()V");
if (this->IDconstructor == NULL)
{
throw std::runtime_error("JAVA_INIT_METHOD_EXCEPTION");
}
this->IDsetInputXML = this->JNIEnvironment->GetStaticMethodID(this->javaClass, "setInputXML", "(Ljava/lang/String;)V");
if (this->IDsetInputXML == NULL)
{
throw std::runtime_error("JAVA_INIT_METHOD_EXCEPTION");
}
this->IDgetInputXML = this->JNIEnvironment->GetStaticMethodID(this->javaClass, "getInputXML", "()Ljava/lang/String;");
//} <- This brace must be further down
if (this->IDgetInputXML == NULL)
{
throw std::runtime_error("JAVA_INIT_METHOD_EXCEPTION");
}
} // <- To here
我確信這只是一個錯字,但如果沒有,它可能是原始例子中問題的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.