Here is an excerpt of C++ code that is called from a Java JVM via 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 ...;
    }

This works in Windows XP but crashes in Windows 7 with an access violation exception, in the line

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

The error message is:

First-chance exception at 0x77355F29 (ntdll.dll) in java.exe: 0xC0000005: Access violation reading location 0x002B0D52.

I'd be thankful for any clues.

JRE version: 6.0_27-b07, Java VM: Java HotSpot(TM) Client VM (20.2-b06 mixed mode windows-x86 ), C++ Code was built with Visual Studio 2010.

有帮助吗?

解决方案

The documentation for GetStringUTFChars() states:

Returns a pointer to an array of UTF-8 characters of the string. This array is valid until it is released by ReleaseStringUTFChars.

The documentation for ReleaseStringUTFChars() states (where string is the first argument and utf is the second argument):

Informs the virtual machine implementation that native code no longer needs access to the native string utf. The utf argument is a pointer derived from string using GetStringUTFChars.

In the posted code, dllName.c_str() is being passed as the second argument to ReleaseStringUTFChars() which is incorrect as c_str() is owned by dllName (std::string's constructor makes a copy of its argument) and is not dervied from pDllName. The fact this works on one platform and not another suggests undefined behaviour.

To correct:

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

/* Use 'dllName' */
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top