原贴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. 如何禁用电脑USB接口

    方法一,BIOS设置法 重新启动计算机,在开机过程中,点击键盘上的“Delete”键,进入BIOS设置界面,选择“Integrated Peripherals”选项,展开后将“USB 1.1 Cont ...

  2. 第二十六节,Python内置函数

    Python3.0内置函数 abs() 取数字的绝对值,也就是无论是正数还是负数取它的绝对值格式:abs(目标变量)返回:数字类型 #!/usr/bin/env python # -*- coding ...

  3. linux下制作u盘启动盘

    格式化u盘为fat32 fdisk -l #查看U盘盘符,或者 df -T umount /dev/sdb #先卸载u盘 mkfs.vfat /dev/sdb #格式化为fat32模式,或者 mkfs ...

  4. 第十四章:使用CSS3进行增强

    1.为不支持某些属性的浏览器使用polyfill:如果想弥合较弱的浏览器和较强的浏览器之间的功能差异,可以使用polyfill(通常又称作垫片),通常用js实现.但是有些较弱的浏览器运行JS的速度要慢 ...

  5. LeetCode OJ 96. Unique Binary Search Trees

    Given n, how many structurally unique BST's (binary search trees) that store values 1...n? For examp ...

  6. 如何使用 AngularJS 的 ngShow 和 ngHide

    今天我们来看看怎样使用Angular的ngShow 和ngHide 指令来完成它们听起来应该完成的,显示和隐藏! 它们应该做的事 ngShow 和ngHide 允许我们显示或隐藏不同的元素.这有助于创 ...

  7. JVM 设置

    按照基本回收策略分 引用计数(Reference Counting) 标记-清除(Mark-Sweep) 复制(Copying) 标记-整理(Mark-Compact) 按分区对待的方式分 增量收集( ...

  8. 去掉input text后面的叉

    如题 input[type=text]::-ms-clear{ display: none; } input::-webkit-search-cancel-button{ display: none; ...

  9. screen 链接远程桌面

    screen     开一个新的screen窗口 screen -ls 查看已经存在的所有screen窗口 screen -r  208111  进入这个窗口 ctrl+a+d  退出screen,回 ...

  10. 推翻自己和过往,重学自定义View

    http://blog.csdn.net/lfdfhl/article/details/51671038 深入探讨Android异步精髓Handler 站在源码的肩膀上全解Scroller工作机制 A ...