Chinaunix首页 | 论坛 | 博客
  • 博客访问: 701456
  • 博文数量: 108
  • 博客积分: 3236
  • 博客等级: 中校
  • 技术积分: 906
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-04 21:23
文章分类

全部博文(108)

文章存档

2011年(33)

2010年(75)

我的朋友

分类: LINUX

2010-06-26 11:09:38

 
    最近这个把星期都在忙着解决一个问题:i.mx35开发板上的中文显示问题。花了不少时间,也遇到很多问题(还有不少奇怪的问题),到目前为止还是没能解决。虽然问题没能解决,但是总结还是要写的。
    首先把个人的遇到的情况说说:
       1、环境:
          虚拟机:VMWare 6.5(fedora 9中文版)
          开发板:i.mx35(ARM11)
 
       2、需求:
          很简单:应用程序在板子上运行时,中文显示正确
 
       3、目前状况:
          U盘挂载:mount -t vfst -o iocharset=cp936 /dev/sda1 /mnt/usb后,U盘中中文目录能显示正常。
          nfs挂载:中文目录显示乱码
          应用程序:中文显示乱码。
 
       4、结果:
          还未解决。痛苦中。
          相关贴:
 
 
    中文显示基本操作及异常解决方案
          A、locale相关:
             (原理性的东西见后面附内容,这里只写一点点操作用得着的东西)
             相关的一些文件:
                /usr/share/i18n,/usr/share/locale,(字符编码相关)
                /usr/lib/locale,(localedef命令后自动生成,包括locale-archive和字符集)
                /usr/bin/locale,/usr/bin/localedef。(locale和localedef命令)
             命令:
                locale
                  将有关当前语言环境或全部公共语言环境的信息写到标准输出上。,结果如图:

                  这里的设置存在一个优先级:当LC_ALL或LANG设定后,其他会自动设置成和LC_ALL或LANG(LC_ALL与LANG间互不影响)相同或对应字符集。
 
                locale -a
                  显示系统当前支持的字符集。(好像和/usr/lib/locale目录下的一样)
               
              localedef
                  转化语言环境和字符集描述(charmap)源文件以生成语言环境数据库
                  语法:localedef [ ] [ Charmap ] [ SourceFile ] [ LinkOptions ] [ MethodFile ]
                  示例:localedef -f GB2312 -i zh_CN zh_CN.gb2312
 
                iconv
                  将文件中的字符或字符序列从一个代码集转换到另一个代码集。
                  语法:iconv [选项...] [文件...]
                  选项:
                      输入/输出格式规范:
                         -f, --from-code=名称 原始文本编码
                         -t, --to-code=名称 输出编码
                      信息:
                         -l, --list 列举所有已知的字符集
                      输出控制:
                         -c 从输出中忽略无效的字符
                         -o, --output=FILE 输出文件
                         -s, --silent 关闭警告
                      --verbose 打印进度信息
                  示例:iconv -f gb2312 -t UTF-8
                  使用方法(代码中),如下(来自网络):

iconv函数族的头文件是iconv.h,使用前需包含之。
#include <iconv.h>
iconv函数族有三个函数,原型如下:
(1) iconv_t iconv_open(const char *tocode, const char *fromcode);
此函数说明将要进行哪两种编码的转换,tocode是目标编码,fromcode是原编码,该函数返回一个转换句柄,供以下两个函数使用。
(2) size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);
此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间。 (3) int iconv_close(iconv_t cd);
此函数用于关闭转换句柄,释放资源。
例子1: 用C语言实现的转换示例程序

/* f.c : 代码转换示例C程序 */
#include <iconv.h>
#define OUTLEN 255
main()
{
char *in_utf8 = "姝e?ㄥ??瑁?";
char *in_gb2312 = "正在安装";
char out[OUTLEN];

//unicode码转为gb2312码

rc = u2g(in_utf8,strlen(in_utf8),out,OUTLEN);
printf("unicode-->gb2312 out=%sn",out);
//gb2312码转为unicode码

rc = g2u(in_gb2312,strlen(in_gb2312),out,OUTLEN);
printf("gb2312-->unicode out=%sn",out);
}
//代码转换:从一种编码转为另一种编码

int code_convert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int 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;
}
//UNICODE码转为GB2312码

int u2g(char *inbuf,int inlen,char *outbuf,int outlen)
{
return code_convert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);
}
//GB2312码转为UNICODE码

int g2u(char *inbuf,size_t inlen,char *outbuf,size_t outlen)
{
return code_convert("gb2312","utf-8",inbuf,inlen,outbuf,outlen);
}

例子2: 用C++语言实现的转换示例程序

/* f.cpp : 代码转换示例C++程序 */
#include <iconv.h>
#include <iostream>

#define OUTLEN 255

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 *in_utf8 = "姝e?ㄥ??瑁?";
char *in_gb2312 = "正在安装";
char out[OUTLEN];

// utf-8-->gb2312

CodeConverter cc = CodeConverter("utf-8","gb2312");
cc.convert(in_utf8,strlen(in_utf8),out,OUTLEN);
cout << "utf-8-->gb2312 in=" << in_utf8 << ",out=" << out << endl;

// gb2312-->utf-8

CodeConverter cc2 = CodeConverter("gb2312","utf-8");
cc2.convert(in_gb2312,strlen(in_gb2312),out,OUTLEN);
cout << "gb2312-->utf-8 in=" << in_gb2312 << ",out=" << out << endl;
}


 
 
     存在问题及部分解决方案(有些错误可能与开发板及个人环境有关)
             A、GCC编译:configure:error:cannot compute suffix of object files:cannot compile
                             这个问题可能主要是路径错误或是某些包不存在。
                             如我遇到的是因为我的编译器路径没加到PATH中去。
                             还有其他情况:
                                    mpft问题:configure: error: cannot compute suffix of object files: cannot compile解决办法
                                                     GCC4-3-2的编译
                     B、error:asm/socket.h:No such file or directory
                           主要是内核头文件可能不存在
                           可参考:
                                  kernel compilation problem
                                  
                    C、cannot map archive header:invalid argument
                           解决方案:加参数--no-archive。不过不肯定是最佳解决方案。(我的开发板上根本找不到locale-archive文件。)
                           参考:
 
 
        总结下:
               虽然问题没解决,但locale相关的东西还是了解了不少,其间还把GCC交叉编译了几次。也不知道是不是板子不支持(网上说的locale-archive,locale-gen等等,在我的板子里全找不到,重新编译的glic中也没有),网上有个类似问题贴(是个牛人发的,从中学到不少东西,嘿嘿):
               具体问题具体分析:别人的解决方法并不一定适合你
               自己的英语水平还是不行,有待加强。
 
2010/06/26
阅读(1165) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~