Linux下JNI参数中文字符串的处理

来源:互联网 发布:济南打车软件 编辑:程序博客网 时间:2024/06/05 21:54
在windows下编译OK的东东放到linux下就成了问题,即例是java也难逃这样的局限,因为有路径和JNI在,java还得面对具体的平台。
问题是这样的,java中字符串是unicode编码的,当调用的C代码是多字节编码时,传入的字符串参数就必须进行转换,这个在windows下没问题。到了linux平台下呢,是不是也是转成多字节编码呢?网上给了很多的解决方案,大都使用类似下面的一个函数:
  1. char* jstringToAnsi(JNIEnv  *env, jstring jstr )
  2. {
  3.     int length = env->GetStringLength(jstr );
  4.     const jchar* jcstr = env->GetStringChars(jstr, 0 );
  5.     char* rtn = (char*)malloc( length*2+1 );
  6.     int size = 0;
  7.     //size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL );// window使用这个
  8.         size = wcstombs(rtn, (const wchar_t*)jcstr, length*2+1);// linux使用这个
  9.     if( size <= 0 )
  10.         return NULL;
  11.     env->ReleaseStringChars(jstr, jcstr );
  12.     rtn[size] = 0;
  13.     return rtn;
  14. }
我也试图用这样的函数来做字节流的转换,但是不能成功。Java下用unicode编码是不会有问题的,为什么转换后的字符串是乱码呢?原因只有一个,就是linux下可能用的不是多字节编码(GBK或GB2312)。怎么查linux下的字符编码设置呢,google之,原来是放在i18n中:
 vi /etc/sysconfig/i18n
果然不是多字节编码,文件上写着:LANG="zh_CN.UTF-8"。好了既然是UTF8,而JNI又有从java的字符串中得到utf8的方法,解决起来就容易了,上面的函数写成下面的样子就得了:
  1. char* jstringToUTF(JNIEnv* env, jstring jstr) {
  2.   int length = env->GetStringLength(jstr);
  3.   const char* utfStr = env->GetStringUTFChars(jstr, 0);
  4.   char* rtn = (char*)malloc( length*2+1 );
  5.   strcpy(rtn, utfStr);
  6.   env->ReleaseStringUTFChars(jstr, utfStr);
  7.   return rtn;
  8. }

搞清楚字符的源编码和目标编码,轻松搞定问题。