所以我有从我的Java程序通过JNI调用的这个C++程序,代码如下:
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"的更新?
谢谢.
NewStringUTF()
创建一个新的java.lang.String - 换句话说,就是Java堆上的一个对象,当没有对它的引用时,它将被收集.
或者你在问otherString
?我不知道是什么FormatMessage
,但它看起来像是在C堆上分配内存.如果是这种情况,那么是的,你必须明确释放那个记忆.
通过设置otherString
为常量字符串,您可以更加努力地生活.不要那样做.相反,NewStringUTF()
在if/else的块内调用,在第二种情况下释放本机C字符串.
您不必担心NewStringUTF分配的内存,因为Java垃圾收集器会处理这些内存.
但是,当您将FORMAT_MESSAGE_ALLOCATE_BUFFER传递给FormatMessage时,您必须释放lpMsgBuf(即您必须使用LocalFree来释放该缓冲区),请参阅FormatMessage文档.