首页 > 代码库 > ARM开发板上iconv调用失败的解决方法
ARM开发板上iconv调用失败的解决方法
当前流行的字符编码格式有:US-ASCII、ISO-8859-1、UTF-8、UTF-16BE、UTF-16LE、UTF-16、GBK、GB2312等,其中GBK、GB2312是专门处理中文编码的。而libiconv是一个常用的编码转换库,支持常用的多种编码之间的转换。在Linux下,工具链gcc有专门的libiconv库,所有不用移植,但在arm-linux下就没那么幸运了,需要我们额外移植libiconv库,不过,过程还是比较简单的。
一、字符编码转换libiconv库介绍
libiconv是一个常用的编码转换库,支持常用的多种编码之间的转换。主要函数有:
#include <iconv.h>
iconv_ticonv_open(constchar *tocode, const char *fromcode);
size_ticonv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
int iconv_close(iconv_tcd);
iconv_open是打开一个编码流,类似于打开一个编码管道(通道),出错则返回-1;
iconv用于具体输入的转换,如果出错,则返回 -1,否则返回 0;
iconv_close是关闭该管道(通道)。
如果对于大量需要转换的编码,上述函数covert不适合该方式,一是内存的限制不能一次调用,二是若分多次调用会频繁打开一个编码管道(通道),导致资源浪费,最好的办法还是拆开该函数根据情况使用。
二、arm-linux移植过程
1)http://www.gnu.org/software/libiconv/ 下载 libiconv-1.14.tar.gz
2)./configure CC=arm-hismall-linux-gcc --target=arm-linux--host=arm-hismall-linux --prefix=$PWD/out --enable-shared--enable-static
3) make
4) make install
上述命令执行完成后会在libiconv目录下生成新的out目录,该目录下存在4个目录分别是:
bin include lib share
在lib目录下为生成的库文件,其中一个为preloadable_libiconv.so,把它下载到开发板
的lib目录下,然后再设置开发板的系统环境变量:
$ export LD_PRELOAD=/lib/preloadable_libiconv.so
然后再执行应用程序即可,正常运行。
三、实例unicode.cpp
//#include <iconv.h> #include <iostream> #include <string.h> #include "./iconv.h" using namespace std; // 代码转换操作类 class CodeConverter { private: iconv_t cd; public: // 构造 CodeConverter(const char *from_charset, const char *to_charset) { cd = iconv_open(to_charset, from_charset); } // 析构 ~CodeConverter() { iconv_close(cd); } // 转换输出 int convert(char *inbuf, int inlen, char *outbuf, int outlen) { char **pin = &inbuf; char **pout = &outbuf; memset(outbuf, 0, outlen); return iconv(cd, pin, (size_t *)&inlen, pout, (size_t *)&outlen); } }; int main(int argc, char **argv) { char *gb2312 = "我是中国人"; char out0[256] = {0}; char out1[256] = {0}; // gb2312-->utf-8 CodeConverter cc0 = CodeConverter("gb2312","utf-8"); cc0.convert(gb2312, strlen(gb2312)+1, out0, 256); cout << "gb2312-->utf-8 in=" << gb2312 << ",out0=" << out0 << endl; // utf-8-->gb2312 CodeConverter cc1 = CodeConverter("utf-8", "gb2312"); cc1.convert(out0, strlen(out0)+1, out1, 256); cout << "utf-8-->gb2312 in=" << out0 << ",out1=" << out1 << endl; return 0; }
arm-hismall-linux-g++ unicode.cpp -L./-liconv //静态库然后nfs下载到板子上或直接运行就ok了。
如果遇到iconv转换异常,可用perror("iconv")来查看错误提示,以上代码我在FreeBSD下进行utf-8 -> gb2312转换失败,原因是iconv_open的两个参数都是小写的,而通过man iconv或iconv -l看到iconv支持的所有编码字符串均为大写。
ARM开发板上iconv调用失败的解决方法