C语言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究竟是不如在头里还是高位以眼前可能还是只要看转换前后的编码具体对比。

转http://blog.csdn.net/liujian885/article/details/6536897