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编码库来 ...
随机推荐
- iosiOStextView实现文字高度自适应
跟为textView设置提示性文字一样 需要在textView的代理方法中实现如下 如有偏差 请谅解 定义UITextView,实现UITextViewDelegate: -(UITextVie ...
- 翻译-你必须知道的28个HTML5特征、窍门和技术
摘自by zhangxinxu from http://www.zhangxinxu.com 本文地址:http://www.zhangxinxu.com/wordpress/?p=1058 前端的发 ...
- WKWebView与Js交互
首先打开webstorm,将最下面h5拷贝到html中.然后导入工程 #define kMessageHandlerName @"mymobile" 1.创建配置类 - (WKWe ...
- java常量和变量的定义规则,变长参数的使用
首先是定义的一般规则,类名首字母全部大写,常量全部大写用下划线分隔,变量用驼峰形式.注意使用long赋值用L时不能写小写的L要写大写的,不然会和数字“1”傻傻分不清. 下面是举例: public cl ...
- 《JS权威指南学习总结--4.13运算符》
一.typeof运算符 typeof是一元运算符,放在其单个操作数的前面,操作数可以是任意类型.返回值为表示操作数类型的一个字符串. 例如: typeof x ...
- hdu_5274_Dylans loves tree(树剖)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5274 题意:给一棵树和叶子的值,然后有单点修改操作和询问区间操作,询问的是每一个值出现的奇偶次数,如果 ...
- php过滤提交数据 防止sql注入攻击
规则 1:绝不要信任外部数据或输入 关于 Web 应用程序安全性,必须认识到的第一件事是不应该信任外部数据.外部数据(outside data) 包括不是由程序员在 PHP 代码中直接输入的任何数据. ...
- Vim常用命令【转载】
下面基本是vim的基本用法,刚开始学习可能有些不习惯.但贵在坚持,即使不习惯,也要坚持使用,做到不经过思考就能操作,你会发现真的很方便.很多操作可以通过不同的命令达到,我这里只列出常用的. 基础命令 ...
- springboot 打包
springboot 打包 先clean 然后 maven package 通过命令java -jar target/GoshenWepPro-0.1.0.jar运行程序
- IOS抓包工具paros的使用
一,环境安装,软件安装 1.下载安装java JDK for Mac,可以从Oracle官网下载(但是一般Oracle的都是最新的版本的),或者从苹果的开发者网站下载,我是从苹果官网下载的javafo ...