JNI中的JVM-Crash调用ReleaseStringUTFChars,仅适用于Windows 7,Windows XP

Tim*_*eek 2 c++ java windows java-native-interface jvm-crash

以下是通过JNI从Java JVM调用的C++代码的摘录:

(JNIEnv *pJniEnv, jobject, jstring pDllName)
    {
           string dllName(pJniEnv->GetStringUTFChars(pDllName, NULL));

           // stuff happens here like
           HINSTANCE loadedDll = LoadLibrary(dllName.c_str());

           pJniEnv->ReleaseStringUTFChars(pDllName, dllName.c_str());

           return ...;
    }
Run Code Online (Sandbox Code Playgroud)

这适用于Windows XP,但在Windows 7中崩溃,并且存在访问冲突异常

 pJniEnv->ReleaseStringUTFChars(pDllName, dllName.c_str());
Run Code Online (Sandbox Code Playgroud)

错误消息是:

java.exe中0x77355F29(ntdll.dll)的第一次机会异常:0xC0000005:访问冲突读取位置0x002B0D52.

我会感谢任何线索.

JRE版本:6.0_27-b07,Java VM:Java HotSpot(TM)客户端VM(20.2-b06混合模式windows-x86),C++代码是使用Visual Studio 2010构建的.

hmj*_*mjd 7

GetStringUTFChars()各州的文件:

返回指向字符串的UTF-8字符数组的指针.此数组在ReleaseStringUTFChars释放之前有效.

ReleaseStringUTFChars()状态的文档(string第一个参数在哪里,utf是第二个参数):

通知虚拟机实现本机代码不再需要访问本机字符串utf.utf参数是使用GetStringUTFChars从字符串派生的指针.

在发布的代码中,dllName.c_str()正在作为第二个参数传递,因为(的构造函数生成其参数的副本)所拥有的第二个参数ReleaseStringUTFChars()是不正确的,并且不会从中删除.这在一个平台而不是另一个平台上工作的事实表明未定义的行为.c_str()dllNamestd::stringpDllName

纠正:

const jbyte* pDllName_string = pJniEnv->GetStringUTFChars(pDllName, NULL);
std::string dllName(pDllName_string);
pJniEnv->ReleaseStringUTFChars(pDllName, pDllName_string);

/* Use 'dllName' */
Run Code Online (Sandbox Code Playgroud)