之前字符编码转换一直用的libicuuc.so,下面贴上libicuuc.so的使用方法:
void (*ucnv_convert)(const char *, const char *, char * , int32_t , const char *, int32_t,int32_t*) = 0; void * init() { int VOIDSIZE = sizeof(void*); NDKLOGI("void size is %d",VOIDSIZE); void* pDL = NULL; if(VOIDSIZE == 4) //32bit pDL = dlopen("/system/lib/libicuuc.so", RTLD_LAZY); else if(VOIDSIZE == 8) //64 bit pDL = dlopen("/system/lib64/libicuuc.so", RTLD_LAZY); else pDL = NULL; if (0 == pDL) { NDKLOGI("load libicuuc.so failure"); NDKLOGE("load libicuuc.so failure"); return pDL; } ucnv_convert = (void (*)(const char *, const char *, char * , int32_t , const char *, int32_t,int32_t*))dlsym(pDL, "ucnv_convert_3_8"); char hanshu_name[256]= {0}; int index = 0; while (0 == ucnv_convert) { sprintf(hanshu_name,"ucnv_convert_4%d",index); ucnv_convert = (void (*)(const char *, const char *, char * , int32_t , const char *, int32_t,int32_t*))dlsym(pDL, hanshu_name); if (ucnv_convert != 0) { return pDL; } index ++; if (index>9) { break; } } //android4.3.x index = 0; while (0 == ucnv_convert) { sprintf(hanshu_name,"ucnv_convert_5%d",index); ucnv_convert = (void (*)(const char *, const char *, char * , int32_t , const char *, int32_t,int32_t*))dlsym(pDL, hanshu_name); if (ucnv_convert != 0) { return pDL; } index ++; if (index>9) { break; } } //android9 index = 0; while (0 == ucnv_convert) { sprintf(hanshu_name,"ucnv_convert_6%d",index); ucnv_convert = (void (*)(const char *, const char *, char * , int32_t , const char *, int32_t,int32_t*))dlsym(pDL, hanshu_name); if (ucnv_convert != 0) { return pDL; } index ++; if (index>9) { break; } } NDKLOGI("%s","find ucnv_convert failure"); NDKLOGE("%s","find ucnv_convert failure"); return pDL; } int code_convert(const char *from_charset,const char *to_charset,const char *inbuf, size_t inlen, char *outbuf, size_t outlen) { if (ucnv_convert) { int err_code = 0; ucnv_convert(to_charset,from_charset ,(char *)outbuf ,outlen ,(const char *)inbuf ,inlen ,&err_code); return err_code; } return 0; } 调用code_convert即可完成字符编码转换。 最近android版本升级到了android11,在android11设备上,libicuuc.so 出现了无法dlopen的情况,android10的时候也出现过,当时没重视。为了解决这个问题,考虑使用iconv库,要求minsdk为api23,abi采用arm64-v8a,交叉编译后,生成了libiconv.so,调用方法如下: int code_convert(const char *from_charset,const char *to_charset,const char *inbuf,size_t inlen,char *outbuf,size_t outlen) { int rc; const char **pin = &inbuf; char **pout = &outbuf; iconv_t cd = iconv_open(to_charset,from_charset); if ((iconv_t)(-1) == cd) return -1; memset(outbuf,0,outlen); if (iconv(cd,const_cast<char **>(pin),&inlen,pout,&outlen)==-1) return -1; iconv_close(cd); return 0; } 目前成功测试了GBK 和 UTF-8 字符集之间的编码转换。