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

时间:2012-10-12 14:47:16

标签: java c++ 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 ...;
    }

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

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

错误消息是:

  

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构建的。

1 个答案:

答案 0 :(得分:7)

GetStringUTFChars()州的文档:

  

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

ReleaseStringUTFChars()个州的文档(其中string是第一个参数,utf是第二个参数):

  

通知虚拟机实现本机代码为   更长时间需要访问本机字符串utf。 utf论点   是使用GetStringUTFChars从字符串派生的指针。

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

要更正:

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

/* Use 'dllName' */