一、libiconv库引入

libiconv库是一个基于GNU协议的开源库,主要是解决多语言编码处理转换等应用问题由于历史原因,国际化的文字常常由于语言或者国家的原因使用不同的编码。

随着互联网时代的到来,通过互联网进行文字交流也逐渐增多:浏览外国的网站,这个时候字符编码的转换变得尤为重要。这带来了一个问题,就是许多字符在某一种编码方式中没有。为了解决这种混乱,Unicode的编码方式被建立。 Unicode是一种超级编码包含了所有这些编码的字符集,因此一些新的文本格式像XML的默认编码方式就是Unicode.

但是很多老式的计算机还在使用当地的传统的字符编码方式。而一些程序,例如邮件程序和浏览器必须能在这些不同的用户编码之间作转换。其他的一些程序则内置支持Unicode,以顺利支持国际化的处理,但是仍然有在Unicode和其他的传统编码之间转换的需求。GNU的libiconv就是为这两种应用设计的编码转换库。

当前流行的字符编码格式有:US-ASCII、ISO-8859-1、UTF-8、UTF-16BE、UTF-16LE、UTF-16、GBK、GB2312等,其中GBK、GB2312是专门处理中文编码的。在Linux下,工具链gcc有专门的libiconv库,所以不用移植,但在arm-linux下就没有那么幸运了,需要我们额外的移植libiconv库。

二、libiconv库介绍

Libiconv是一个常用的编码转换库,支持常用的多种编码之间的转换,主要函数有:

#include <iconv.h>
iconv_t iconv_open(const char *tocode, const char *fromcode);
size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
int iconv_close(iconv_t cd);
  • iconv_open()是打开一个编码流,类似于打开一个编码管道(通道),出错则返回-1;

  • iconv()用于具体的输入转换,如果出错则返回-1,成功返回0;

  • iconv_close()是关闭管道(通道)。

在Linux系统中也有一个iconv命令,该命令是用来转换文件的编码方式的(Convert encoding of given files from one encoding to another),比如它可以将UTF8编码的转换成GB18030的编码,反过来也行,同时iconv命令在调试此类程序时用得着。

三、libiconv库获取

libiconv库源码包下载页面如下:http://www.gnu.org/software/libiconv/

四、libiconv库移植

移植与安装libiconv库非常简单,只需要执行如下命令即可:

$ ./configure --prefix=/usr/local
$ make
$ make install

详细的安装过程可见源码包中的INSTALL.generic文档,里面详细介绍了编译选项的不同作用,也可以通过命令“./configure --help”进行查看。下面是我编译ARM使用的libiconv库使用的命令:

首先传递安装目录:

$ ./configure --prefix=/work/study/libiconv/libiconv_build/ CC=arm-linux-gcc --host=arm
$ make
$ make install

五、libiconv库使用

当我们编译程序时,若提示如下错误:

cannot find -liconv
collect2: ld return 1 exit status

或者:

undefined reference to ‘libiconv_open’
collect2: ld return 1 exit status

就是因为没有安装libiconv包的原因,安装方法如上4.4节libiconv库移植。下面介绍如何使用libiconv库。

#include <iconv.h>
iconv_t iconv_open(const char *tocode, const char *fromcode);
size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
int iconv_close(iconv_t cd);

针对iconv()函数,第一个参数是iconv_t的描述符,第二个参数表示下一次转换位置的指针的指针,第三个参数表示最多处理inbytesleft个字节,第四个参数表示下一次转换后输出的指针的指针,第五个参数表示最多输出outbytesleft个字节。

iconv()函数一次转换一个多字节符,每次字符转换,inbuf增加已转换的字节数,inbytesleft相应的减少已转换的字节数;对应地,outbuf和outbytesleft作相应的增加修改,同时修改cd的转换状态。iconv()函数返回本次调用中转换的字符数,可逆的转换不计入。

注意iconv()会改变输入的5个参数值,所以我们在使用的时候一定要注意,使用的时候或者传副本,或者先把值记录下来,使用后恢复;而且iconv()并不输出‘\0’,所以我们得自己加‘\0’。

【使用实例】:

__inline int char_code_convert(char *from_charset,char *to_charset,char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
    iconv_t cd;
    int rc;
    char **pin = &inbuf;
    char **pout = &outbuf;
    cd = iconv_open(to_charset,from_charset);
    if (cd==0)
        return -1;
    memset(outbuf,0,outlen);
    if (iconv(cd,pin,&inlen,pout,&outlen) == -1)
        return -1;
    iconv_close(cd);
    return 0;
} 

想了解更多有关嵌入式Linux驱动、应用、常用开源库、框架、模式、重构等相关相关的主题内容,请长安下面图片,关注我的公众号(只有技术干货分享,不拉稀摆带!)。

来自  https://www.jianshu.com/p/6a713de65ea4