GNU iconv

GNU iconv


一、关键函数

1、iconv_open()
    iconv_open(DestinationCharsets, SourceCharSets)

2、iconv()
[XSI] [Option Start] #include <iconv.h>

size_t iconv(iconv_t cd, char **restrict inbuf,
       size_t *restrict inbytesleft, char **restrict outbuf,
       size_t *restrict outbytesleft); [Option End]

二、使用异常

1、使用问题①

UTF-8编码的汉字字符串正在安装,即{0xE6,0xAD,0xA3, 0xE5, 0x9C, 0xA8, 0xE5, 0xAE , 0x89 ,0xE8 ,0xA3 ,0x85, 00},在将其转换成GB2312编码的时候出现了错误,提示:

Libiconv:: libiconv invalid incomplete  multibyte character or wide character

查得原因是,iconv()函数的目标字符集和原字符集顺序写反了。iconv_open(DestinationCharsets, SourceCharSets)。例如,如果想将字符集从UTF-8转换到gb2312,调用方法是:iconv_open("gb2312","UTF-8")

2、使用问题②

libiconv munmap_chunk() invalid pointer
问题出现在函数

size_t iconv(iconv_t cd, char **restrict inbuf,
        size_t *restrict inbytesleft, char **restrict outbuf,
        size_t *restrict outbytesleft); [Option End]

因为参数**outbuf*outbuf均发生了变化,在后面调用那个函数free()的时候,需要用*outbuf原始保存的值(要定义一个临时变量来保存),但是不能用*outbuf这个参数。

REFER:解决munmap_chunk(): invalid pointer和Segmentation fault的bug

三、将libiconv移植到ARM-Linux(Freescale/飞思卡尔)

1、编译libiconv

./configure  CC=arm-linux-gcc --host=arm-linux --enable-shared --prefix=/home/csh/arm/libiconv

其中,选项--host的赋值,只能是arm-linux,一定不能少-linux,否则找不到生成动态库的工具。

2、使用问题

iconv_open: invalid argement,在PC电脑上运行良好,刚移植到ARM上立刻出错。但是使用iconv --list命令,显示包含GB2312字符集。
解决办法:不用/lib/libiconv.so,而是调用/lib/preloadable_libiconv.so。其中,编译libiconv库的时候生成的lib有如下几个:

charset.alias  libcharset.la  libcharset.so.1      libiconv.la  libiconv.so.2      preloadable_libiconv.so
libcharset.a   libcharset.so  libcharset.so.1.0.0  libiconv.so  libiconv.so.2.5.1

export LD_PRELOAD=/lib/preloadable_libiconv.so
./arm_newutf8togb

REFER: ARM开发板上iconv_open("utf-8", "gb2312") 调用失败的解决方法

四、原代码

#include <iconv.h>
#include <stdio.h>
#include <locale.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>


void printeverychar(char *text)
{
	int size=strlen(text);
	int i=0;
	for(;i<size;i++)
	{
		printf("%s[%d] is %d\n",text, i, text[i]);
	}
}

int main(int argc, char * argv[])
{
    size_t ret;
    //const char in_utf8[] = {0xE6,0xAD,0xA3, 0xE5, 0x9C, 0xA8, 0xE5, 0xAE , 0x89 ,0xE8 ,0xA3 ,0x85, 00};
    char *in_utf8 = "正在安装";
    char *in_gb2312= "正在安装";
    char **pin = &in_utf8;

    size_t src_len = strlen(in_utf8)+1;
	printf("UTF8 string length is %d\n", src_len);

	printf("utf8 string is %s\n",in_utf8);
   	printeverychar(in_utf8); 


    size_t dest_len = 3*src_len;
    char *szDest = (char *)malloc(dest_len);
	if ( szDest == NULL) 
		return -1;
	memset(szDest,0, dest_len);
	char *pdest = szDest;

    char **pout = &szDest;
//	pin=in_utf8;


    iconv_t conv = iconv_open("gb2312","UTF-8");
    if (conv == (iconv_t)-1)
    {
        perror("iconv_open:");
        return -1;
    }

    ret = iconv(conv, pin, &src_len, pout, &dest_len);
    if (ret == -1)
    {
		printf("Ret = %d\n", ret);
        perror("iconv:");
        return -1;
    }
	else{
		printf("Ret = %d\n", ret);
	}
    

	printf("dest_len is %d\n", dest_len);
    printf("String-out is %s\n",pdest);
	printeverychar(pdest);


    iconv_close(conv);

    if (pdest != NULL) 
		free(pdest);
   
    return 0;
}

上面的代码,将正在安装UTF-8转成gb2312编码格式。Note:文件保存的时候,一定要用UTF-8模式保存。

参考:


1、Fucntion iconv()
2、HP iconv

posted @ 2016-09-06 17:10  xiulug  阅读(1243)  评论(0编辑  收藏  举报