JNI освобождает память, чтобы избежать утечки памяти - PullRequest
8 голосов
/ 07 октября 2009

Итак, у меня есть эта программа на C ++, которая вызывается через JNI из моей программы на Java, следующий код:

    JNIEXPORT jstring JNICALL Java_com_entrust_adminservices_urs_examples_authn_LdapAuthenticator2_takeInfo(JNIEnv *env, jobject obj, jstring domain, jstring id, jstring idca, jstring password) 
{
    const char *nt_domain;
    const char *nt_id;
    const char *nt_password;
    HANDLE hToken = 0;

    bool aut = false;

    nt_domain = env->GetStringUTFChars(domain, NULL);
    nt_id = env->GetStringUTFChars(id, NULL);
    nt_password = env->GetStringUTFChars(password, NULL);

      aut = LogonUser(nt_id, nt_domain, nt_password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &hToken );

      /* release buffers */
    env->ReleaseStringUTFChars(domain, nt_domain);
    env->ReleaseStringUTFChars(id, nt_id);
    env->ReleaseStringUTFChars(password, nt_password);
    /* release the login handle */
    CloseHandle(hToken);

    if(aut)
    {
        return env->NewStringUTF("true"); 
    }

    DWORD dwError = GetLastError();
      LPVOID lpMsgBuf;

      FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT ), (LPTSTR) &lpMsgBuf, 0, NULL );

    return env->NewStringUTF((const char*)lpMsgBuf); //returns the contents of lpMsgBuf (error)
}

в этой строке от второй до последней jstring newString = env->NewStringUTF((const char*)otherString); никогда не освобождается, но возвращается, не приведет ли это к возможной утечке памяти? есть ли способ обойти это?

Также возможно ли, чтобы вместо возврата строки я возвращал логическое значение (как возвращено функцией LogonUser) вместо jstring и вместо этого добавил ссылку «errormessage» для передачи в метод и обновил это? моя программа на Java сможет видеть обновление "errormessage"?

Спасибо.

Ответы [ 2 ]

9 голосов
/ 07 октября 2009

NewStringUTF() создает новый java.lang.String - другими словами, объект в куче Java, который будет собираться, когда на него больше нет ссылок.

Или вы спрашиваете о otherString? Я не знаю, что делает FormatMessage, но похоже, что он выделяет память в куче Си. Если это так, то да, вы должны явно освободить эту память.

Вы усложняете свою жизнь, иногда устанавливая otherString в постоянную строку. Не делай этого. Вместо этого вызовите NewStringUTF() внутри блоков вашего if / else, а во втором случае освободите нативную строку C.

6 голосов
/ 08 октября 2009

Вам не нужно беспокоиться о памяти, выделенной NewStringUTF, так как об этом позаботится сборщик мусора Java.

Но вы должны освободить lpMsgBuf при передаче FORMAT_MESSAGE_ALLOCATE_BUFFER в FormatMessage (т. Е. Вы должны использовать LocalFree для освобождения этого буфера), см. Документацию FormatMessage .

...