簡體   English   中英

CallObjectMethod不返回字符串

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM