您尚未登录。

楼主 #1 2018-04-21 15:28:54

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,339
积分: 9202

使用gnu工具链自带iconv完成gbk/gb2312到unicode字符编码双向转换

参考链接: Using iconv to convert strings to ISO-8859-1 in C/C++

使用gnu工具链自带iconv完成gbk/gb2312到unicode字符编码双向转换





离线

楼主 #2 2018-04-24 08:57:29

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,339
积分: 9202

Re: 使用gnu工具链自带iconv完成gbk/gb2312到unicode字符编码双向转换

QQ20180424084806.png

如果你的嵌入式系统一直使用gbk字符集,
然后需要显示u盘文件(FAT/FAT32格式),
一定需要这个iconv了.

windows下FAT/FAT32 短文件名(8.3格式)使用gb2312/gbk字符集
但是长文件名存储是用unicode16 (little endian)字符集.

QQ20180424084806.png





离线

楼主 #3 2018-04-24 14:51:28

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,339
积分: 9202

Re: 使用gnu工具链自带iconv完成gbk/gb2312到unicode字符编码双向转换

QQ20180424144902.png

Ubuntu一切正常, 但是嵌入式Linux就挂了:

#./test
iconv_open: Invalid argument





离线

楼主 #4 2018-04-24 16:02:16

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,339
积分: 9202

Re: 使用gnu工具链自带iconv完成gbk/gb2312到unicode字符编码双向转换

终于找到 iconv_open() 出现 Invalid argument 错误的解决方法了,

把工具链下面的 gconv 文件夹全部拷贝到根文件系统的 /usr/lib 目录下即可
cp /usr/local/arm-2014.05/arm-none-linux-gnueabi/libc/usr/lib/gconv /usr/lib

如果觉得太大,可以按需要剪裁。

比如,我只用到了 gbk 与 utf-8,
那么 /usr/lib/gconv/ 目录只需要添加以下文件:

-rwxr-xr-x    1 root     root        127394 Apr 25 08:55 GBK.so
-rwxr-xr-x    1 root     root         28720 Apr 25 08:55 UTF-16.so
-rwxr-xr-x    1 root     root         56284 Apr 25 08:55 gconv-modules




离线

楼主 #5 2018-04-24 16:10:47

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,339
积分: 9202

Re: 使用gnu工具链自带iconv完成gbk/gb2312到unicode字符编码双向转换

又有新问题来了

error iconv(): Argument list too long





离线

楼主 #6 2018-04-24 16:22:03

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,339
积分: 9202

Re: 使用gnu工具链自带iconv完成gbk/gb2312到unicode字符编码双向转换

https://github.com/drichardson/examples/blob/master/iconv/utf8-to-utf32.c

只找到了这个:

// If I make the outbufbytesleft 1 smaller, I get an Argument List Too Long error. I don't think
    // gives you any sort of idea of a buffer will be big enough, you're just supposed to call it
    // again to keep going when you run out of space. That said, seems like I should be able to determine
    // an upper bound going from UTF-8 (1-3 bytes per character) to UTF-32 (4 bytes per character). Perhaps
    // the +1 is for some null terminator, but I haven't read anything to that effect.

google自动翻译:

如果我使outbufbytesleft 1变小,我会得到一个参数列表太长的错误。 我不认为
给你任何一种缓冲区的想法都足够大,你只需要调用它
在空间不足时再次继续前进。 这就是说,似乎我应该能够确定
从UTF-8(每个字符1-3个字节)到UTF-32(每个字符4个字节)的上限。 也许
+1是针对某个空终止符,但我没有阅读任何相关内容。

但是同样的代码在ubuntu没有问题。





离线

楼主 #7 2018-04-24 16:32:39

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,339
积分: 9202

Re: 使用gnu工具链自带iconv完成gbk/gb2312到unicode字符编码双向转换

找到一篇文章: https://blog.csdn.net/ying_593254979/article/details/12133391

在软件开发中不可避免的需要用到字符集的转换;转换方法很多如自行编写字符集转换库、利用Windows提供之MultiByteToWideChar函数等;自行编写相对周期较长,而利用MultiByteToWideChar等函数进行转换在跨平台移值时带来很大的不方便;所以在本文里我们将讲述如何利用在Linux与Windows下都可用的libiconv库进行字符集的转换。
我们可以从http://www.gnu.org/software/libiconv/上下载最新版本的libiconv;本文里以libiconv-1.9.2-1.exe为例子说明安装与使用方法;libiconv的安装非常的方便,就和大多数的Windows应用程序安装一样直接Step by Step就可以了;在安装过程中会提示你是否下载源代码,源代码说白了对我们也没有多大的用处所以就不选择下载源代码;安装完之后在libiconv的安装目录下的man/pdf目录中有一个libiconv-man.pdf,这个文件就是libiconv相关函数的说明;所以如果你对libiconv还不是很熟悉的话请看一下这个文件。
为了在VC6中使用libiconv库我们必需对VC6进行相应的设置;从VC6的菜单栏中选择ToolsàOptions..,在弹出的对话框中选择Directories选项卡,在Show directories for下拉框中选择Include files,在最下方的Directories:中添加上libiconv安装目录下的include目录,如下图(图1-1)所示:

   
                                     图1-1
这样我们就配置了iconv.h文件查找目录;由于libiconv要用到libiconv.lib所以接下来我们应该配置一下libiconv.lib文件的查找目录;在图1-1的Show directories for下接框中选择Library files,在最下方的Directories:列表中添加上libiconv安装目录下的lib目录;OK配置完成点击OK按钮就可以了;为了测试方便我们应该所libiconv安装目录下之bin目录下的libiconv2.dll复制到系统的System32目录下。
转换例子如下:
#include <stdio.h>
#include <string.h>
//包函libiconv库头文件
#include <iconv.h>
//导入libiconv库
#pragma comment(lib,"libiconv.lib")

int ChangeCode( const char* pFromCode,
                              const char* pToCode,
                              const char* pInBuf,
                              size_t* iInLen,
                              char* pOutBuf,
                              size_t* iOutLen );

int main( int argc, char* argv[] )
{
       char sInBuf[100];
       char sOutBuf[100];
       size_t iInLen = 0;
       size_t iOutLen = 100;
       int iRet;
       strcpy( sInBuf, "测试Test Source" );
       memset( sOutBuf, 0x00, 100 );
       iInLen = strlen( sInBuf );
       iRet = ChangeCode( "GBK", "UTF-16", sInBuf, &iInLen, sOutBuf, &iOutLen );
       return 0;
}

int ChangeCode( const char* pFromCode,
                              const char* pToCode,
                              const char* pInBuf,
                              size_t* iInLen,
                              char* pOutBuf,
                              size_t* iOutLen )
{
       int iRet;
       //打开字符集转换
       iconv_t hIconv = iconv_open( pToCode, pFromCode );
       if ( -1 == (int)hIconv )
       {
              return -1;//打开失败,可能不支持的字符集
       }
       //开始转换
       iRet = iconv( hIconv, (const char**)(&pInBuf), iInLen, (char**)(&pOutBuf), iOutLen );
       //关闭字符集转换
       iconv_close( hIconv );
       return iRet;
}

字符集的转换就是这么的简单;当然如果你有兴趣的话在Linux下也去安装一下libiconv然后把上面那段代码放到Linux下用gcc编译一下看看。

如果出现错误:iconv: Argument list too long。将OutLen设置大一点

那么我得去改改代码。





离线

楼主 #8 2018-04-24 16:52:18

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,339
积分: 9202

Re: 使用gnu工具链自带iconv完成gbk/gb2312到unicode字符编码双向转换

终于解决, 原来是我自己挖的坑, iconv( ) 函数最后一个参数忘记初始化了.

iconv(conv, &gbk_str, &inbytes, &out, &outbytes)





离线

楼主 #9 2018-04-24 17:01:13

晕哥
管理员
注册时间: 2017-09-06
已发帖子: 9,339
积分: 9202

Re: 使用gnu工具链自带iconv完成gbk/gb2312到unicode字符编码双向转换

至此终于在ucgui  gbk 字符集系统把U盘功能全部整合进去了。





离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn