原贴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. json格式数据,将数据库中查询的结果转换为json, 然后调用接口的方式返回json(方式一)

    调用接口,无非也就是打开链接 读取流 将结果以流的形式输出 将查询结果以json返回,无非就是将查询到的结果转换成jsonObject ================================ ...

  2. Git 暂存区的概念

    工作区:我们在电脑里面能看到的目录,也就是我们用git init 命令初始化的那个目录.里面包含要添加文件和需要提交的文件,在这个目录下的文件,修改和变更,我们的git都能感知的到. 版本库:工作区有 ...

  3. http GET

    向php脚本中传参数可以用http GET 方法,比如要向file.php传两个参数v1和v2.则可以这么做 file.php?v1=&v2= (一个链接而已,直接编辑URL即可传参数了) 这 ...

  4. 用 js 做 URL 跳转带来的 Referer 丢失问题.

    http 302 重定向是可以保持 referer 的.例:在 A 页面上提交登录表单到 B,B 返回一个重定向页面到 C,在 C 处理里面检查 Referer 可知道它的来源是 A 而不是 B. 但 ...

  5. Long-Polling, Websockets, SSE(Server-Sent Event), WebRTC 之间的区别

    在下面的示例中,客户端指的是浏览器,服务器指的是网站服务器主机. 为了更好的理解这些知识点,你应该简单了解典型的http网站是如何工作的. 普通的http: 客户端从服务器端请求网页 服务器作出相应的 ...

  6. 数据库NULL和 ‘’ 区别

    NULL判断时 : IS NOT NULL ''判断时: !=''

  7. Windows下搭建PHP开发环境【总结】

    一.准备工作-下载所需软件 Apache 进入apache服务器官网http://httpd.apache.org/ ,下面是下载的教程:http://jingyan.baidu.com/articl ...

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

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

  9. wpf计时器

    wpf应用程序间隔一段时间触发一个事件,代码如下: public MainWindow() { InitializeComponent(); DispatcherTimer timer = new D ...

  10. 【floyd 多源最短路】 poj 1125

    #include <stdio.h> #include <iostream> #include <memory.h> using namespace std; ][ ...