为什么要移植iconv库?
在项目进行过程中,有这样一个需求。每辆车的车牌由汉字和字母、数字组成,例如:[京A99999],当然我们在这基础上还添加了车牌的颜色,所以车牌信息在数据传输过程中显示的是[蓝牌:京A99999]。车牌信息是通过树莓派用OPENCV做的图像识别来获取的,这个信息首先会通过局域网发送给网关,协议是V3.0.网关需要将该信息重新封装成json数据包pub给mqtt代理。此过程中汉字数据无需转码,全部用的是utf-8格式。但是底层的显示节点(迪文屏),需要显示车牌信息,这个信息由网关通过zigbee发送给显示节点。尴尬的是,迪文屏不支持utf-8格式,所以网关下发的utf-8的汉字码无法显示。因此网关需要在车牌信息下发前将汉字转码为GB2312格式才行。
Ubuntu下默认支持iconv函数组,但是ARM默认是不支持的
Ubuntu下utf-8转GB2312码例程:
#include <stdio.h>
#include <iconv.h>
#include <string.h>
int utf8togb2312(char *sourcebuf, size_t source_len, char *destbuf, size_t dest_len)
{
iconv_t cd;
if((cd = iconv_open("gb2312","utf-8")) == (iconv_t)-1){
perror("iconv_open");
printf("cd : %d\n",cd);
return -1;
}
printf("cd : %d\n",cd);
memset(destbuf,0,dest_len);
char **source = &sourcebuf;
char **dest = &destbuf;
if(-1 == iconv(cd, source, &source_len, dest, &dest_len))
return -1;
iconv_close(cd);
return 0;
}
int gb2312toutf8(char *sourcebuf, size_t source_len, char *destbuf, size_t dest_len)
{
iconv_t cd;
if((cd = iconv_open("utf-8","gb2312")) == 0)
return -1;
memset(destbuf,0,dest_len);
char **source = &sourcebuf;
char **dest = &destbuf;
if(-1== iconv(cd, source, &source_len,dest, &dest_len))
return -1;
iconv_close(cd);
return 0;
}
void test(void)
{
unsigned char *p = "蓝牌:京A99999";
unsigned char dest_gb2312[32];
int ret,i;
ret = utf8togb2312(p,16,dest_gb2312,32);
printf("utf-8 : %s\n",p);
printf("gb2312 : %s\n",dest_gb2312);
for(i=0;i<17;i++){
printf("%02x ",dest_gb2312[i]);
}
}
int main(int argc, const char *argv[])
{
unsigned char temp[17] = {0xe8,0x93,0x9d,0xe7,0x89,0x8c,0x3a,0xe4,0xba,0xac,0x41,0x39,0x39,0x39,0x39,0x39,0x00};
unsigned char hhh[24] = {0xe5, 0x96,0x9c,0xe6,0x98,0x8e,0xe4,0xbd,0xa0,0xe5,0xa5,0xbd,0xe5,0x9d,0x8f};
test();
return 0;
}
Ubuntu下编译程序:
gcc test.c -o iconv
Ubuntu下运行结果如下:
runner@ubuntu64-vm:~$./iconv
cd : 25800208
utf-8 : 蓝牌:京A99999
gb2312 : ����:��A99999
c0 b6 c5 c6 3a be a9 41 39 39 39 39 39 00 00 00 00
runner@ubuntu64-vm:~$
转换得到的码,能够在迪文屏上正常显示,说明转码成功。当然有一些在线工具也可以直接转成GB2312
ARM平台编译程序:
arm-none-linux-gnueabi-gcc test.c -o iconv
ARM平台没有移植libiconv运行结果如下:
[root@farsight /]# ./iconv
iconv_open: Invalid argument
cd : -1
utf-8 : 蓝牌:京A99999
@b2312 : d1
64 31 0d 40 00 00 00 00 00 00 00 00 f4 83 00 00 00
[root@farsight /]#
ARM平台移植iconv库
• 获取libiconv库源码,我这里获取的是新的libiconv-1.15.tar.gz网址如下:
https://ftp.gnu.org/gnu/libiconv/
• 解压库源码包,将下载的库源码拷贝到ubuntu虚拟机下,解压。
tar xvf libiconv-1.15.tar.gz
• 配置libiconv库
./configure --host=arm-none-linux-gnueabi --prefix=/source/rootfs/usr/local/iconv --enable-shared --enable-static
--host 为交叉编译工具链的名称
--prefix 为库安装的路径
--enable-shared 为生成动态库
--enable-static 为生成静态库
• 编译libiconv库
make
• 安装libiconv 库
make install
• 配置文件系统,支持libiconv库
vi etc/profile
添加如下内容:(这部分内容在libiconv1.15/README中有提到)
LD_LIBRARY_PATH=/usr/local/iconv/lib:$LD_LIBRARY_PATH
export PATH LD_LIBRARY_PATH
export LD_PRELOAD=/usr/local/iconv/lib/preloadable_libiconv.so
• 重启系统,运行之前编译的测试程序,结果如下:
[root@farsight /]# ./iconv
cd : 69640
utf-8 : 蓝牌:京A99999
gb2312 : 6Ɔ:¾©A99999
c0 b6 c5 c6 3a be a9 41 39 39 39 39 39 00 00 00 00
[root@farsight /]#