2

以下は、JavaJVMからJNIを介して呼び出される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 ...;
    }

これはWindowsXPで機能しますが、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++コードはVisualStudio2010で構築されました。

4

1 に答える 1

8

状態のドキュメントGetStringUTFChars():

文字列の UTF-8 文字の配列へのポインターを返します。この配列は、ReleaseStringUTFChars によって解放されるまで有効です。

状態のドキュメントReleaseStringUTFChars()(stringは最初の引数、utfは 2 番目の引数):

ネイティブ コードがネイティブ文字列 utf にアクセスする必要がなくなったことを仮想マシンの実装に通知します。utf 引数は、GetStringUTFChars を使用して文字列から派生したポインターです。

投稿されたコードでは、が所有する(のコンストラクターがその引数のコピーdllName.c_str()を作成する) であり、 から派生していないため、 が 2 番目の引数として渡されています。これがあるプラットフォームでは機能し、別のプラットフォームでは機能しないという事実は、未定義の動作を示唆しています。ReleaseStringUTFChars()c_str()dllNamestd::stringpDllName

なおす:

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 に答える