0

尝试将当前正在按下键的窗口的名称从 JNI C 代码发送到 java 方法时,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 在遇到上述代码段时崩溃。我知道 jvm 崩溃是由于将无效参数传递给 java 函数(通过 C 代码)。如果是这样,请解释我如何发送参数。我需要将当前窗口的标题发送到 java 函数。

4

2 回答 2

2

因为你的方法有一个 String 作为它的参数,你应该给它一个jstring实例。JVM 无法理解 aTCHAR是什么。因此,您需要使用以下方法将您的字符转换为 java 字符串:

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

编辑:如果TCHARwchar_t,即 16 位并且可以转换为 jchar,那么您需要使用NewString而不是NewStringUTF. 你可以在这里阅读更多。

于 2012-10-13T08:48:58.913 回答
0

当我第一次看到TCHAR时,我会说“哦!太棒了,你可以编写一个在 Win9X 和 WinNT 中都可以工作的代码,并且还可以通过一个定义调用最佳平台函数:_UNICODE”。但随着时间的推移,我发现这让许多开发人员感到困惑。没有什么是独立的 as TCHAR,它是 char 的 typedef_UNICODE未定义和 typedefwchar_t否则,因此取决于项目的定义,它会改变。但另一方面,Java 方法只期望其中一个(char 或 wchar_t,但我不知道其中哪一个),所以如果你定义_UNICODE在您的项目中(这将在新的 IDE 中自动完成)和 Java 方法需要一个 char* 然后您传递一个 wchar_t* 然后您将错误的类型传递给函数并且字符串的长度将被计为一个(因为 wchar_t 是2 个字节,它将大部分单字节 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 回答