jvm在尝试将TCHAR类型发送到接受字符串作为参数的java函数时崩溃
jvm crashes when trying to send TCHAR type to java function that accepts string as argument
当试图将当前按键所在窗口的名称从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:如果TCHAR
是wchar_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!
- 如何使用Luacneneneba API正确读取字符串和表参数
- 如何使用字符串文字作为宏参数
- 如何将可变长度参数联接为字符串
- 如何使用字符串find_first_of缓冲区形式(size_t n 参数)
- 具有字符串化的可变参数宏的现代/通用方法
- C++ 构造函数参数:字符串、整数、整数、整数
- 当C 中的系统调用conconculables时,参数字符串中的字符损失
- 模板参数字符串与整数
- #define 参数字符串化,但宽字符串 L " instead of "
- std::getline 用于 ifstream,使用参数字符串或 char *
- 通过参数字符串化宏调用模板函数
- 可变参数字符串比较
- 为什么位集的构造函数有参数字符串::charT 零,字符串::charT one)
- c++中stdbind在带有参数(字符串)的函数中的用法
- 当使用字符变量作为参数(字符串转换为字符)时,Std::rename()文件将不起作用
- C/ c++预处理器中的宏参数字符串化为宽字符串字面值
- 如何比较Visual C++中的参数字符串
- C++错误:推断出参数'T'字符串与常量字符的冲突类型 *
- 传递参数字符串,其中包含空格和引号
- 函数参数字符串通过引用传递