以下是通过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中出现访问冲突exception,在行中
pJniEnv->ReleaseStringUTFChars(pDllName, dllName.c_str());
错误消息是:
java.exe中0x77355F29(ntdll.dll)的第一次机会exception:0xC0000005:访问冲突读取位置0x002B0D52。
我会感谢任何线索。
JRE版本:6.0_27-b07,Java VM:Java HotSpot(TM)客户端VM(20.2-b06混合模式Windows-x86),C ++代码使用Visual Studio 2010构build。
GetStringUTFChars()
的文档声明:
返回一个指向字符串的UTF-8字符数组的指针。 这个数组在ReleaseStringUTFChars发布前是有效的。
ReleaseStringUTFChars()
状态的文档(其中string
是第一个参数, utf
是第二个参数):
通知虚拟机实现本地代码不再需要访问本地字符串utf。 utf参数是使用GetStringUTFChars从字符串派生的指针。
在发布的代码中, dllName.c_str()
被作为ReleaseStringUTFChars()
的第二个参数传递,这是不正确的,因为c_str()
被dllName
拥有( std::string
的构造函数生成它的参数的副本 ),而不是来自pDllName
。 这个事实在一个平台而不是另一个平台上的事实表明了未定义的行为
纠正:
const jbyte* pDllName_string = pJniEnv->GetStringUTFChars(pDllName, NULL); std::string dllName(pDllName_string); pJniEnv->ReleaseStringUTFChars(pDllName, pDllName_string); /* Use 'dllName' */