原贴http://topic.csdn.net/u/20101022/16/1b2e0cec-b9d2-42ea-8d9c-4f1bb8320a54.html?r=70149216 ,看过并动手实现,记录下来以备再用。

如果是在java层,有String类可以很好的转换各种编码,在ndk下面就没有现成的公开的工具,不过可以用icu4c。

ICU4C 是IBM的国际化开发组件ICU的C语言实现版本。在android系统里也有实现。ndk里面并没有公开可用的api,需要自己加载动态库来调用转换函数。

android下icu库路径为"/system/lib/libicuuc.so",主要用到的转换函数为ucnv_convert_?_?。这里的问号是根据版本的不同函数名也不一样。在2.2的模拟器中的libicuuc.so中此函数名为ucnv_convert_4_2,在2.1模拟器中为ucnv_convert_3_8,貌似要根据版本不同来分开对待,还没发现可以统一的办法。

函数原型:

void ucnv_convert(const char *, const char *, char * , int32_t , const char *, int32_t,int32_t*);

用法:

//声明函数指针
void (*ucnv_convert)(const char *, const char *, char * , int32_t , const char *, int32_t,int32_t*)=0;
//加载动态库
void* pDL = dlopen("/system/lib/libicuuc.so", RTLD_LAZY);
//这里以android2.2为例,函数名就是ucnv_convert_4_2
ucnv_convert = (void (*)(const char *, const char *, char * , int32_t , const char *, int32_t,int32_t*))dlsym(pDL, "ucnv_convert_4_2");
//加载成功就可以用了
if(ucnv_convert){
    char* cbuf = "...";
    char buffer[100];
    int errcode = 0;
    //utf8是目标编码,ucs2是原字符编码
     //buffer是存放转换出来的字符的缓冲,给了100字节
     //cbuf是要转换的字符串指针
     //errcode是错误编码,具体可网上搜索
    ucnv_convert("utf8","ucs2", buffer, 100, cbuf, strlen(cbuf),&errcode);
}

转换成功后的字符串就放在buffer里面,如果出错了就会在errcode里面放错误代码。

如标题所示,ndk下还有一个宽字符,也就是wchar_t的问题,跟其他平台移植也是个麻烦的事。

linux下wchar_t默认是4个字节,而windows下(包括CE,MOBILE)和symbian下都是2个字节。解决的办法是在android.mk文件中,找到LOCAL_CFLAGS 为其加上编译开关 -fshort-wchar(如果没有此项就手动写上),如 LOCAL_CFLAGS :=  -fshort-wchar  。这样强制编译器用2个字节处理wchar_t,不过编译时会有warning,可以不管。

这样虽然编译器处理成2个字节,但是预编译的库libc等依然是4个字节,会导致wcslen等函数无法使用(其实ndk下wcslen本来就是废的),解决的办法可以重新编译libc,不过最简单的还是自己实现wcslen就行了。

下面的代码是copy网上的,具体哪里的忘了,可以把wchar_t转换成char字符串,这样就可以用icu库随意转换了。

//取得wchar_t字符串长度
int wlen(const wchar_t* strString){
 int i=0;
 while (1) {
  if (strString[i] == 0) {
   break;
  }else{
   i++;
  }
 }
 return i;
}

char *W2C(const wchar_t *pw , char *pc)
{
      *pc++ = *pw >> 8 ;
      *pc = *pw ;
      return 0 ;
}
//转换字符串
char *wstr2cstr(const wchar_t *pwstr, char *pcstr, size_t len) {
 char *ptemp = pcstr;
 if (pwstr != NULL && pcstr != NULL) {
  size_t wstr_len = wlen(pwstr);
  len = (len > wstr_len) ? wstr_len : len;
  while (len-- > 0) {
   W2C(pwstr, pcstr);
   pwstr++;
   pcstr += 2;
  }
  *pcstr = '/0';
  return ptemp;
 }
 return 0;
}

使用wstr2cstr就可以转换出来。这里还有个字节序的问题,在W2C函数里面,一个wchar_t转到char究竟是低位在前还是高位在前恐怕还是要看转换前后的编码具体对待。

Android NDK 下的宽字符编码转换及icu库的使用(转)的更多相关文章

  1. Linux 下查看文件字符编码和转换编码

    Linux 下查看文件字符编码和转换编码 如果你需要在Linux中操作windows下的文件,那么你可能会经常遇到文件编码转换的问题.Windows中默认的文件格式是GBK(gb2312),而Linu ...

  2. iconv字符编码转换

    转自 http://blog.csdn.net/langresser_king/article/details/7459367 iconv(http://www.gnu.org/software/li ...

  3. php字符编码转换之gb2312转为utf8(转)

    在php中字符编码转换我们一般会用到iconv与mb_convert_encoding进行操作,但是mb_convert_encoding在转换性能上比iconv要差很多哦.string iconv ...

  4. Char Tools,方便的字符编码转换小工具

    工作关系,常有字符编码转换方面的需要,写了这个小工具 Char Tools是一款方便的字符编码转换小工具,基于.Net Framework 2.0 Winform开发 主要功能 URL编码:URLEn ...

  5. php 字符编码转换函数 iconv mb_convert_encoding比较

    在使用PHP处理字符串时,我们经常会碰到字符编码转换的问题,你碰到过iconv转换失败吗? 发现问题时,网上搜了搜,才发现iconv原来有bug ,碰到一些生僻字就会无法转换,当然了配置第二个参数时, ...

  6. 编码问题 php字符编码转换类

    各种平台和软件打开显示的编码问题,需要使用不同的编码,根据我们不同的需求. php 字符编码转换类,支持ANSI.Unicode.Unicode big endian.UTF-8.UTF-8+Bom ...

  7. Python—字符编码转换、函数基本操作

    字符编码转换 函数 #声明文件编码,格式如下: #-*- coding:utf-8 -*- 注意此处只是声明了文件编码格式,python的默认编码还是unicode 字符编码转换: import sy ...

  8. day4学python 字符编码转换+元组概念

    字符编码转换+元组概念 字符编码转换 #coding:gbk //此处必声明 文件编码(看右下角编码格式) #用来得到python默认编码 import sys print(sys.getdefaul ...

  9. erlang中字符编码转换(转)

    转自:http://www.thinksaas.cn/group/topic/244329/ 功能说明: erlang中对各种语言的编码支持不足,此代码是使用erlang驱动了著名的iconv编码库来 ...

随机推荐

  1. 4-static(静态变量)关键字

    1.使用static声明属性 static声明全局属性2.使用static声明方法 直接通过类名调用3.注意点 使用static方法的时候,只能访问static声明的属性和方法,而非static声明的 ...

  2. Redis中connect和pconnect的区别

    首先先介绍下connect和pconnect的区别.connect:脚本结束之后连接就释放了. pconnect:脚本结束之后连接不释放,连接保持在php-fpm进程中.所以使用pconnect代替c ...

  3. postfix日志分析pflogsumm

    1.pflogsumm功能:统计接收.投递.转发.延时.反弹.拒绝.保留.丢弃的邮件统计发件人和收件人 统计发送和接受方主机/域名 统计SMTPD连接数...... 2.安装# yum install ...

  4. 用For Each语句对Session.Contents树组进行遍历

    <%@ LANGUAGE=VBScript codepage ="936" %> <% Option Explicit %> 您的sessionID号是:& ...

  5. JS-加载页面的时候自动选择刚才所选择option

    <body class="no-skin" onload="option_auto(${pd.PACK_SORT})"> <select na ...

  6. 1.1 sikuli 安装

    JRE7不支持sikuli,必须下载JRE6   更新号必须大于35 sikuli下载: http://www.cr173.com/soft/52775.html 或参照 http://www.cnb ...

  7. ignite中的sql查询

    ignite中进行sql查询需要对要查询的cache和字段进行配置,可以在xml中配置,也可以在代码中配置或进行注解,我用的是xml配置: <!-- 配置cache --> <pro ...

  8. POJ1308 Is It A Tree?

    题目大意:和HDU1272-小希的迷宫题目一样, 如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径 ...

  9. NSIndexPath 延伸

    转载自:http://my.oschina.net/u/2560887/blog/602095?fromerr=Dy4vj5Jd 这个类的实例描述了一个嵌套数组中特定节点的路径,一般叫做索引路径.1. ...

  10. [Android]通过JNI访问并操作Bitmap的元素,支持RGB565和ARGB8888

    [Android]通过JNI访问并操作Bitmap的元素,支持RGB565和ARGB8888 标签: androidbitmapjni 2014-05-09 20:35 2985人阅读 评论(1) 收 ...