2

以下是通过 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) Client VM(20.2-b06 混合模式 windows-x86),C++ 代码是使用 Visual Studio 2010 构建的。

4

1 回答 1

8

状态的文档GetStringUTFChars()

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

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

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

在发布的代码中,dllName.c_str()作为第二个参数传递,该参数ReleaseStringUTFChars()不正确,因为c_str()(dllNamestd::string构造函数复制了它的参数) 并且不是从pDllName. 这适用于一个平台而不是另一个平台的事实表明未定义的行为。

纠正:

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

/* Use 'dllName' */
于 2012-10-12T15:05:37.083 回答