jvm在尝试将TCHAR类型发送到接受字符串作为参数的java函数时崩溃

jvm crashes when trying to send TCHAR type to java function that accepts string as argument

本文关键字:参数 字符串 java 崩溃 函数 TCHAR 类型 jvm      更新时间:2023-10-16

当试图将当前按键所在窗口的名称从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函数。

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

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

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

当我第一次看到TCHAR时,我会说"哦!太棒了,你可以写一个在Win9X和WinNT中都能工作的代码,也可以用一个定义调用最好的平台函数:_UNICODE"。但随着时间的推移,我发现这让许多开发人员感到困惑。没有什么能像TCHAR那样独立,当没有定义_UNICODE时,它是char的typedef,否则它是wchar_t的typedef,所以根据项目的定义,它会发生变化。但另一方面,Java方法只期望它们中的一个(char或wchar_t,但我不知道它们中的哪一个),因此,如果你在项目中定义_UNICODE(这将在新的IDE中自动完成),Java方法需要一个char*,那么你传递了一个wchar_t*,然后你传递了错误的类型到函数,字符串的长度将被计算为一(因为wchar_t是2个字节,它将大部分单字节的char映射到char+一个额外的'\0'),如果你传递char*到函数,而它需要一个wchar_t*,它可能会产生错误(例如访问违规),因为:

TCHAR title[500]; // will be converted to char title[500];
// now fill it and it may contain 'abcde some junk data'
// Java want to interpret this as wchar_t* and expect '' 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!