|
ARM開發(fā)板上iconv_open("utf-8", "gb2312") 調(diào)用失敗的解決方法 應(yīng)用程序代碼如下: static int code_convert(char* from_charset, char* to_charset, char* inbuf, size_t inlen, char* outbuf, size_t outlen) { iconv_t cd; char **pin = &inbuf; char **pout = &outbuf; cd = iconv_open(to_charset, from_charset); if (cd == -1) { perror("iconv_open:"); return -1; } memset(outbuf,0,outlen); if (iconv(cd, pin, &inlen, pout, &outlen) == -1) { //printf("%s: call iconv failed!\n", __FUNCTION__); printf("errno=%d\n", errno); perror("iconv failed:\n"); iconv_close(cd); return -1; } iconv_close(cd); return 0; } static int g2u(char* inbuf, size_t inlen, char* outbuf, size_t outlen) { return code_convert("gb2312", "utf-8", inbuf, inlen, outbuf, outlen); } 開發(fā)環(huán)境為Ubuntu11.10,開發(fā)板為ARM開發(fā)板,交叉編譯器版本為arm-linux-4.4.3. 相同的C源程序,在ubuntu11.10上能夠正常執(zhí)行,而在ARM開發(fā)板則不能正常執(zhí)行,調(diào)用 iconv_open("utf-8", "gb2312") 返回失敗,錯誤信息為“Invalid argument”. 經(jīng)過查詢資料得知iconv相關(guān)函數(shù)為libc中的函數(shù),初步分析得出結(jié)論為有可能是libc版本中 iconv相關(guān)函數(shù)的版本不同造成的,因此要更新iconv相關(guān)函數(shù)。 更新iconv相關(guān)函數(shù)有兩種方法: 第一,更新libc庫; 第二,更新libiconv庫。 第一種方法更新libc庫比較麻煩,因為我們用的是編譯好的交叉編譯器,這中方法需要重新編譯生成 交叉編譯器,并且也需要使用新編譯生成的交叉編譯工具重新編譯應(yīng)用程序,因此本方法代價太大, 采用第二種方法。 第二種方法為只更新libiconv庫,到iconv官網(wǎng)下載最新的庫源碼包,下載地址為: http://ftp./gnu/libiconv/libiconv-1.14.tar.gz 解壓后得到libiconv目錄,閱讀該目錄下Readme文件得出,編譯安裝libiconv庫也有兩種方式: This library can be built and installed in two variants:
- The library mode. This works on all systems, and uses a library `libiconv.so' and a header file `<iconv.h>'. (Both are installed through "make install".) To use it, simply #include <iconv.h> and use the functions. To use it in an autoconfiguring package: - If you don't use automake, append m4/iconv.m4 to your aclocal.m4 file. - If you do use automake, add m4/iconv.m4 to your m4 macro repository. - Add to the link command line of libraries and executables that use the functions the placeholder @LIBICONV@ (or, if using libtool for the link, @LTLIBICONV@). If you use automake, the right place for these additions are the *_LDADD variables. Note that 'iconv.m4' is also part of the GNU gettext package, which installs it in /usr/local/share/aclocal/iconv.m4. - The libc plug/override mode. This works on GNU/Linux, Solaris and OSF/1 systems only. It is a way to get good iconv support without having glibc-2.1. It installs a library `preloadable_libiconv.so'. This library can be used with LD_PRELOAD, to override the iconv* functions present in the C library. On GNU/Linux and Solaris: $ export LD_PRELOAD=/usr/local/lib/preloadable_libiconv.so On OSF/1: $ export _RLD_LIST=/usr/local/lib/preloadable_libiconv.so:DEFAULT A program's source need not be modified, the program need not even be recompiled. Just set the LD_PRELOAD environment variable, that's it! 我在ARM開發(fā)板上采用“The libc plug/override mode”實驗成功,下面介紹編譯過程: 在libiconv目錄下: $./configure --prefix=$PWD/out --host=arm-linux $make $make install 上述命令執(zhí)行完成后會在libiconv目錄下生成新的out目錄,該目錄下存在4個目錄分別是: bin include lib share 在lib目錄下為生成的庫文件,其中一個為preloadable_libiconv.so,把它下載到開發(fā)板 的lib目錄下,然后再設(shè)置開發(fā)板的系統(tǒng)環(huán)境變量: $ export LD_PRELOAD=/lib/preloadable_libiconv.so 然后再執(zhí)行應(yīng)用程序即可,正常運行。
|