當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > FS4412 移植 libiconv庫
為什么要移植iconv庫?
在項(xiàng)目進(jìn)行過程中,有這樣一個需求。每輛車的車牌由漢字和字母、數(shù)字組成,例如:[京A99999],當(dāng)然我們在這基礎(chǔ)上還添加了車牌的顏色,所以車牌信息在數(shù)據(jù)傳輸過程中顯示的是[藍(lán)牌:京A99999]。車牌信息是通過樹莓派用OPENCV做的圖像識別來獲取的,這個信息首先會通過局域網(wǎng)發(fā)送給網(wǎng)關(guān),協(xié)議是V3.0.網(wǎng)關(guān)需要將該信息重新封裝成json數(shù)據(jù)包pub給mqtt代理。此過程中漢字?jǐn)?shù)據(jù)無需轉(zhuǎn)碼,全部用的是utf-8格式。但是底層的顯示節(jié)點(diǎn)(迪文屏),需要顯示車牌信息,這個信息由網(wǎng)關(guān)通過zigbee發(fā)送給顯示節(jié)點(diǎn)。尷尬的是,迪文屏不支持utf-8格式,所以網(wǎng)關(guān)下發(fā)的utf-8的漢字碼無法顯示。因此網(wǎng)關(guān)需要在車牌信息下發(fā)前將漢字轉(zhuǎn)碼為GB2312格式才行。
Ubuntu下默認(rèn)支持iconv函數(shù)組,但是ARM默認(rèn)是不支持的
Ubuntu下utf-8轉(zhuǎn)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 = "藍(lán)牌:京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下運(yùn)行結(jié)果如下:
runner@ubuntu64-vm:~$./iconv
cd : 25800208
utf-8 : 藍(lán)牌:京A99999
gb2312 : ����:��A99999
c0 b6 c5 c6 3a be a9 41 39 39 39 39 39 00 00 00 00
runner@ubuntu64-vm:~$
轉(zhuǎn)換得到的碼,能夠在迪文屏上正常顯示,說明轉(zhuǎn)碼成功。當(dāng)然有一些在線工具也可以直接轉(zhuǎn)成GB2312
ARM平臺編譯程序:
arm-none-linux-gnueabi-gcc test.c -o iconv
ARM平臺沒有移植libiconv運(yùn)行結(jié)果如下:
[root@farsight /]# ./iconv
iconv_open: Invalid argument
cd : -1
utf-8 : 藍(lán)牌:京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網(wǎng)址如下:
https://ftp.gnu.org/gnu/libiconv/
• 解壓庫源碼包,將下載的庫源碼拷貝到ubuntu虛擬機(jī)下,解壓。
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 為生成動態(tài)庫
--enable-static 為生成靜態(tài)庫
• 編譯libiconv庫
make
• 安裝libiconv 庫
make install
• 配置文件系統(tǒng),支持libiconv庫
vi etc/profile
添加如下內(nèi)容:(這部分內(nèi)容在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
• 重啟系統(tǒng),運(yùn)行之前編譯的測試程序,結(jié)果如下:
[root@farsight /]# ./iconv
cd : 69640
utf-8 : 藍(lán)牌:京A99999
gb2312 : 6Ɔ:¾©A99999
c0 b6 c5 c6 3a be a9 41 39 39 39 39 39 00 00 00 00
[root@farsight /]#