1

質問1:以下の関数で、値を返す前にメソッドを呼び出し たいと思い。この場合のように私がそれを行う方法は、アプリケーションがクラッシュする可能性があります。ReleaseStringUTFChars

String JNIXMLDOMDocument::GetXML() const
{
    String strXML;

    jmethodID method = m_JavaEnv->GetMethodID(m_XMLDomDocClass, "GetXML", "(Lorg/w3c/dom/Document;)Ljava/lang/String;");
    if(method == NULL) {
        return NULL;
    }

    jstring jstrXML = (jstring)m_JavaEnv->CallObjectMethod(m_XMLDomDocClassObject, method, m_XMLDomDocument);
    if (jstrXML == NULL) {
    return strXML;
    }

    strXML = m_JavaEnv->GetStringUTFChars(jstrXML, 0);

    /* Question 1:  **/
    m_JavaEnv->ReleaseStringUTFChars(jstrXML, strXML.c_str());

    return strXML;

} /* String GetXML() const **/

質問2:アプリケーションでマルチスレッドを使用している場合、コンストラクターでスレッドをアタッチしてすべての関数で使用し、デストラクタでデタッチするのは正しいですか?

JNIXMLDOMDocument::JNIXMLDOMDocument()
{
    /* Check If the current thread is attached to the virtual machine. **/
    int needToDetach;
    /* Question 2:  **/
    m_JavaEnv = AttachCurrentThread(&needToDetach);
    if (m_JavaEnv != NULL)
    {
        /* Try to find JAVA 'XMLDOMDocument' class. **/
    m_XMLDomDocClass = m_JavaEnv->FindClass("com/fido/android/framework/service/XMLDOMDocument");
    if (m_XMLDomDocClass != NULL) {
        jmethodID constructor = m_JavaEnv->GetMethodID(m_XMLDomDocClass, "<init>", "()V");
        if (constructor != NULL) {
            m_XMLDomDocClassObject = m_JavaEnv->NewObject(m_XMLDomDocClass, constructor);
        }
        else DBG_ERROR(DBG_CTX, ("Can't create object of 'XMLDOMDocument' class!\n"));
    }
    else DBG_ERROR(DBG_CTX, ("Can't find 'XMLDOMDocument' class!\n"));

    /* Try to find 'XMLDOMNode' class. **/
    jclass localXMLDomNodeClass = m_JavaEnv->FindClass("com/fido/android/framework/service/XMLDOMNode");
    if (localXMLDomNodeClass != NULL) {
        jmethodID constructor = m_JavaEnv->GetMethodID(localXMLDomNodeClass, "<init>", "()V");
        if (constructor != NULL) {
            m_XMLDomNodeClassObject = m_JavaEnv->NewObject(localXMLDomNodeClass, constructor);
        }
        else DBG_ERROR(DBG_CTX, ("Can't create object of 'XMLDOMNode' class!\n"));
    }
    else DBG_ERROR(DBG_CTX, ("Can't find 'XMLDOMNode' class!\n"));

    }

} /* JNIXMLDOMDocument() **/
4

2 に答える 2

3

最初の部分:私はあなたStringがどんなタイプかわかりません。const char*どうやら割り当てが可能で、方法があるという事実からc_str()、私はastd::stringまたは同様のものを推測します。さらに推測すると、あなたStringはそれに与えているcstringのコピーを作成しているので、元のcstringを解放しても存続するはずです。Stringしかし、あなたはあなたがから得たものではなく、あなたの内部のcstringを解放していますGetStringUTFChars。したがって、無効なを返していますString

したがって、答えは「はい」ですが、実際にはReleaseStringUTFCharsを呼び出す必要がありますが、正しい方法は次のとおりです。

String strXML;
const char* tempStr = m_JavaEnv->GetStringUTFChars(jstrXML, 0);
strXML = tempStr;
m_JavaEnv->ReleaseStringUTFChars(jstrXML,tempStr);
return strXML;

私は自信を持って2番目の部分に答えることができません、私はNDKに興味がありません。別の質問をしてください。

于 2012-06-11T14:09:23.467 に答える
0

2番目の質問だけに答えるには、十分な情報が提供されていませんが、一般に、両方が同じスレッドによって呼び出された場合は、コンストラクタ/デストラクタのペアを介してアタッチおよびデタッチできます。

于 2012-06-12T00:27:32.273 に答える