0

現在キーが押されているウィンドウの名前を JNI C コードから Java メソッド jvm に送信しようとすると、jvm がクラッシュします。無効な引数が渡されたためだと思います。呼び出しが失敗する理由と、引数を送信する方法を説明してください。

Java メソッドのプロトタイプは次のようになります。

public void storeNameOfForegroundWindow(String windowName) {
  // store in the list
}

JNI C スニペット:

 jmethodID callBackToStoreWindowName = (*env)->GetMethodID(env,cls,"storeNameOfForegroundWindow","(Ljava/lang/String;)V");
 TCHAR title[500];
 GetWindowText(GetForegroundWindow(), title, 500);
 jvalue windowName,*warr;
 windowName.l = title;
 warr = &title;
 (*Env)->CallVoidMethodA(Env,object,callBackToStoreWindowName,warr);

上記のスニペットに遭遇すると、JVM がクラッシュします。Java 関数に無効な引数が渡されたために (C コードを介して) jvm がクラッシュすることがわかっています。その場合は、引数を送信する方法を説明してください。現在のウィンドウのタイトルを Java 関数に送信する必要があります。

4

2 に答える 2

2

メソッドには引数として文字列があるため、jstringインスタンスを指定する必要があります。JVM は a が何であるかを理解できませんTCHAR。したがって、次を使用して文字をJava文字列に変換する必要があります。

(*env)->NewStringUTF(env, title);

編集: の場合、つまり 16 ビットであり、jchar にキャストできる場合は、代わりに を使用する必要がTCHARあります。詳しくはこちらをご覧くださいwchar_tNewStringNewStringUTF

于 2012-10-13T08:48:58.913 に答える
0

を初めて見たときTCHAR、私は「すばらしい。Win9X と WinNT の両方で動作する 1 つのコードを記述でき、1 つの定義だけで最高のプラットフォーム関数を呼び出すことができます: _UNICODE」と言いました。しかし、やがて、これが多くの開発者を混乱させることがわかりました。のようにスタンドアロンのものはなく、 が定義されていないTCHARときは charの typedef、そうでないときは typedef なので、プロジェクトの定義によって変わります。しかし一方で、Javaメソッドはそれらの1つだけを期待しています(charまたはwchar_tのいずれかですが、どちらかはわかりません)。_UNICODEwchar_t_UNICODEプロジェクトで (これは新しい IDE で自動的に行われます)、Java メソッドが char* を期待している場合、wchar_t* を渡している場合、間違った型を関数に渡しているため、文字列の長さは 1 としてカウントされます (wchar_t は2 バイトの場合、1 バイトの char のほとんどを char + 追加の '\0' にマップします)。wchar_t* を想定しているときに char* を関数に渡すと、エラー (アクセス違反など) が発生する可能性があります。理由は次のとおりです。

TCHAR title[500]; // will be converted to char title[500];
// now fill it and it may contain 'abcde\0 some junk data'
// Java want to interpret this as wchar_t* and expect '\0\0' as end of string
// since wchar_t is 2 byte and it may never see it in you string and read beyond
// end of title that is obviously an error!
于 2012-10-13T08:48:59.457 に答える