Вот выдержка из кода C ++, который вызывается из Java JVM через JNI:
(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());
Сообщение об ошибке:
Исключение первого шанса в 0x77355F29 (ntdll.dll) в java.exe: 0xC0000005: расположение чтения нарушения доступа 0x002B0D52.
Я был бы благодарен за любые подсказки.
Версия JRE: 6.0_27-b07, Java VM: клиентская виртуальная машина Java HotSpot (TM) (смешанный режим 20.2-b06, windows-x86), код C ++ был создан с использованием Visual Studio 2010.
Документация для 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' */
Других решений пока нет …