Android NDK 下的宽字符编码转换及icu库的使用(转)
原贴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库的使用(转)的更多相关文章
- Linux 下查看文件字符编码和转换编码
Linux 下查看文件字符编码和转换编码 如果你需要在Linux中操作windows下的文件,那么你可能会经常遇到文件编码转换的问题.Windows中默认的文件格式是GBK(gb2312),而Linu ...
- iconv字符编码转换
转自 http://blog.csdn.net/langresser_king/article/details/7459367 iconv(http://www.gnu.org/software/li ...
- php字符编码转换之gb2312转为utf8(转)
在php中字符编码转换我们一般会用到iconv与mb_convert_encoding进行操作,但是mb_convert_encoding在转换性能上比iconv要差很多哦.string iconv ...
- Char Tools,方便的字符编码转换小工具
工作关系,常有字符编码转换方面的需要,写了这个小工具 Char Tools是一款方便的字符编码转换小工具,基于.Net Framework 2.0 Winform开发 主要功能 URL编码:URLEn ...
- php 字符编码转换函数 iconv mb_convert_encoding比较
在使用PHP处理字符串时,我们经常会碰到字符编码转换的问题,你碰到过iconv转换失败吗? 发现问题时,网上搜了搜,才发现iconv原来有bug ,碰到一些生僻字就会无法转换,当然了配置第二个参数时, ...
- 编码问题 php字符编码转换类
各种平台和软件打开显示的编码问题,需要使用不同的编码,根据我们不同的需求. php 字符编码转换类,支持ANSI.Unicode.Unicode big endian.UTF-8.UTF-8+Bom ...
- Python—字符编码转换、函数基本操作
字符编码转换 函数 #声明文件编码,格式如下: #-*- coding:utf-8 -*- 注意此处只是声明了文件编码格式,python的默认编码还是unicode 字符编码转换: import sy ...
- day4学python 字符编码转换+元组概念
字符编码转换+元组概念 字符编码转换 #coding:gbk //此处必声明 文件编码(看右下角编码格式) #用来得到python默认编码 import sys print(sys.getdefaul ...
- erlang中字符编码转换(转)
转自:http://www.thinksaas.cn/group/topic/244329/ 功能说明: erlang中对各种语言的编码支持不足,此代码是使用erlang驱动了著名的iconv编码库来 ...
随机推荐
- ios沙盒查找图片展示
iOS如何找到自己的沙盒 在ios开发我们会用到沙盒,由于自己对沙盒理解的不够,所以找不到沙盒文件在哪里,当然要知道路径了 例如我的路径 NSString* cachepath = [NSHomeDi ...
- Storm官方文档翻译之创建Storm项目
本文将讲述如何在开发环境创建一个Storm项目,下面是步骤: 1.将Storm的相关jar包添加到classpath中: 2.如果使用多语言开发,也要将多语言目录添加到classpath; 点击sto ...
- how to add a shared lib in C?
http://www.cprogramming.com/tutorial/shared-libraries-linux-gcc.html Basically, 2 steps: 1) make the ...
- js判断当前时间前几天和格式校验
addday天后的日期 function time(addday) { var now= new Date(); nowdate=now.getDate(); //alert(nowdate); no ...
- jarsigner
开发者应用认领说明 Flyme应用中心应用认领,采用Android的apk安装包签名机制来完成.如果你不清楚签名是什么,请联系开发人员协助您. 在Android平台发布应用程序之前,必须经过一个签名流 ...
- centos gdb安装
1. 下载gdb 7.6.1源码包 http://ftp.gnu.org/gnu/gdb/gdb-7.6.1.tar.gz 将源码包放在home目录的Download目录中 2. 解压缩gdb 7.6 ...
- 转 Oracle DBCA高级玩法:从模板选择、脚本调用到多租户
但凡是学过Oracle的同学,对DBCA(Database Configuration Assistant, DBCA)都不会陌生,有了这个工具,使得创建数据库成为可能.而DBCA本身有图形和静默两种 ...
- EL表达式处理字符串 是否 包含 某字符串 截取 拆分...............
EL表达式处理字符串 是否 包含 某字符串 截取 拆分............... JSP页面页头添加<%@ taglib uri="/WEB-INF/taglib/c.tld&qu ...
- execlp("ls","flw","-?",(char *)0) 为什么少了最后的一个参数就不行?
execlp("ls","flw","-?",(char *)0) 为什么少了最后的一个参数就不行?
- 灵感闪现 篇 (一) 2d场景 3d 效果
中途打断一下 ,框架文档的 更新. 另开一篇主题为 灵感闪现的 板块. 在工作生活中,总有发现新事物或新东西 而让自己突然 灵感闪现的时候,那么这个时候,我必须要抓住,并尽快把 这份灵感实现下来. 之 ...