我注意到在Java8中,JNI的GetStringChars()函数似乎不能正确地转换商标字符™,该函数应该可以转换Unicode字符。我对GetStringUTFChars()方法也有同样的问题。
这不是一个大问题,因为有一些简单的解决方法(在调用JNI函数之前从字符串中删除Unicode字符)。
但是由于我在Googling上没有发现类似的问题,所以我来这里看看有没有人对此有解释?(或者我可能在代码中遗漏了什么?)
我使用的是MinGW下的Java8和g++ 4.8。
下面是我的代码片段:
JNIEXPORT void JNICALL Java_MyClass_JNI_myMethod (JNIEnv * env , jobject obj, jstring input_string)
{
const jchar *inp_string = (*env).GetStringChars(input_string, NULL);
const jchar *jch_inp_string = inp_string;
(*env).ReleaseStringChars(input_string, inp_string);
std::cout << jch_inp_string <<'\n';
}举个例子,使用这个函数,如果我输入这个字符串:
Random String™它输出以下内容:
Random Stringâ„¢发布于 2017-04-02 22:55:56
经过对文档的深入研究,我找到了一种解决方法,这是因为java只支持UTF8修改,这意味着它足以打印XML文档,但不能毫无错误地打印拉丁文-1编码的字符。
为此,我从c++回调了java,并让他将修改后的utf8字符转换为符合我需要的编码。虽然我想知道是否有最简单的方法来做到这一点,但我发现非常奇怪的是,JNI本机提供的字符串并不完全符合非常常见的标准。
JNIEXPORT void JNICALL Java_MyClass_JNI_myMethod (JNIEnv * env , jobject obj, jstring input_string){
//this calls back JNI to reformat the string form java UTF8 modified encoding to something more common
const jclass stringClass = env->GetObjectClass(input_string);
const jmethodID getBytes = env->GetMethodID(stringClass, "getBytes", "(Ljava/lang/String;)[B");
const jstring charsetName = env->NewStringUTF("windows-1252");
const jbyteArray stringJbytes = (jbyteArray) env->CallObjectMethod(input_string, getBytes, charsetName);
env->DeleteLocalRef(charsetName);
const jsize length = env->GetArrayLength(stringJbytes);
const jbyte* strBytes = env->GetByteArrayElements(stringJbytes, NULL);
//this make sure our string is C/C++ compliant with null character
//but it seems to work well without too
char* my_string = malloc(length+1);
memcpy( my_string , strBytes, length);
my_string [length] = '\0';
env->ReleaseByteArrayElements(stringJbytes, strBytes , JNI_ABORT);
env->DeleteLocalRef(stringJbytes);
std::cout << my_string << std::endl;
}https://stackoverflow.com/questions/43163819
复制相似问题