以下是通过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构建的。
答案 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' */