我一直在尝试从JNI调用中返回ARABIC字符串。
java方法如下
private native String ataTrans_CheckWord(String lpszWord, String lpszDest, int m_flag, int lpszReserved);
lpszWord:输入英文
lpszDest:忽略
m_flag:忽略
lpszReserved:忽略
现在,当我使用javah生成头文件时,我得到一个带有此签名的C ++头文件
JNIEXPORT jstring JNICALL Java_MyClass_ataTrans_1CheckWord (JNIEnv* env, jobject, jstring, jstring, jint , jint)
现在在这个C ++代码中,我有这样的语句
JNIEXPORT jstring JNICALL Java_MyClass_ataTrans_1CheckWord(JNIEnv* env, jobject, jstring jstrInput, jstring, jint , jint)
{
char aa[10];
char* bb;
char** cc;
bb = aa;
cc = &bb;
jstring tempValue;
const char* strCIn = (env)->GetStringUTFChars(jstrInput , &blnIsCopy);
int retVal = pDllataTrans_CheckWord(strCIn, cc, m_flag, lpszReserved);
printf("Orginal Arabic Conversion Index 0: %s \n",cc[0]); //This prints ARABIC properly
tempValue = (env)->NewString((jchar* )cc[0],10); // convert char array to jstring
printf("JSTRING UNICODE Created : %s \n",tempValue); //This prints junk
return tempValue;
}
我相信ARABIC内容位于指针“cc”的指针内。最后在我的java代码中,我有这样的调用
String temp = myclassInstance.ataTrans_CheckWord("ABCDEFG", "",1, 0);
System.out.println("FROM JAVE OUTPUT : "+temp); //Prints Junk
我无法将一些ARABIC字符退回到我的JAVA代码中。我在做什么不对劲?我已尝试过各种其他替代品,如
tempValue = env->NewStringUTF("شسيشسيشسيشس");
并返回tempValue但没有运气。它在JAVA方面总是垃圾。
答案 0 :(得分:4)
Java字符串在内部UTF-16
,每个字符使用2或4个字节的编码。您的翻译系统似乎返回以MBCS
(多字节字符集)编码的字符串 - 每个字符1个N字节。
JNI NewString
函数需要将数据编码为UTF-16
,并且您将其传递给其他内容 - 因此在java中您将获得垃圾数据。您的信息缺少的一件事是您的翻译系统使用哪种编码。我假设它是UTF-8
,并使用MultiByteToWideChar
转换为java期望的格式。以下代码假定您在Windows上执行此操作 - 如果没有,请指定平台,并查看例如iconv
库。
int Len = strlen(cc[0])*2+2;
wchar_t * Buffer = (wchar_t *) malloc(Len);
MultiByteToWideChar(CP_UTF8, 0, cc[0], -1, Buffer, Len);
tempValue = (env)->NewString((jchar* )Buffer,wcslen(Buffer));
free(Buffer);
如果您将字符串作为其他代码页,请替换上面的CP_UTF8。
作为旁注,如果实际的编码是 UTF-8,您可以简单地将cc[0]
传递给NewStringUTF
- 此函数将UTF-8处理为内部UTF-16转换。