由于项目需要,需要将GB2312格式的编码转换成UTF-8格式,用android本身的jni函数中的转换格式总是乱码,如果底层发上来的数 据,通过 jni的NewStringUTF()函数将数据转换成utf-8,但是发送到上层显示依然是乱码,也就是说NewStringUTF函数没有起 作 用,linux下有个iconv命令可以转换编码格式,于是想把iconv移植到android上,调用iconv中的函数来转换编码格式。
iconv源码下载
首先,下载iconv代码,将下载的代码解压,进入解压后的源码目录,现在linux环境下进行配置,执行 comfigure脚本,产生linux下config.h文件,因为config.h里定义了很多linux平台下的宏,
编译方法:
首先执行./configure --build=x86_64-pc-linux-gnu --host=arm-linux-eabi
然后执行make,然后在源码目录下创建一个Android.mk文件通过android来编译。
Android.mk写法
LOCAL_PATH:= $(callmy-dir)
include $
(CLEAR_VARS)
LOCAL_MODULE
:= libiconv
LOCAL_CFLAGS
:= \
-Wno-multichar \
-DANDROID \
-DLIBDIR="c" \
-DBUILDING_LIBICONV \
-DIN_LIBRARY

LOCAL_SRC_FILES
:= \
libcharset
/lib/localcharset.c \
lib
/iconv.c \
lib
/relocatable.c

LOCAL_C_INCLUDES
+= \
$
(LOCAL_PATH)/include \
$
(LOCAL_PATH)/libcharset \
$
(LOCAL_PATH)/lib \
$
(LOCAL_PATH)/libcharset/include \
$
(LOCAL_PATH)/srclib
include $
(BUILD_SHARED_LIBRARY)

将你写的代码放到android源码中,可以放到externl目录下,这样你就可以使用android的编译环境编译你的代码了
可以使用mm命令编译。
这样会编译生成一个动态库libiconv.so

编译完后会放到 out/target/product/你的产品名/system/lib文件中

在你的代码中用到iconv_open() iconv()函数时需要在你的代码中加上编译出来的libiconv.so动态库
Android.mk文件写法
LOCAL_PATH :=$(call my-dir)
include $(CLEAR_VARS)

LOCAL_MODULE_TAGS = eng

LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_SRC_FILES := \
main.c \
list.c \
serial.c \
interface.c \
communication.c


LOCAL_C_INCLUDES += \ //这里是引用iconv源码中的头文件,你可以把iconv源码中的include libcharset
$(LOCAL_PATH)/include \ lib libcharset/include srclib 等目录放到你的代码中
$(LOCAL_PATH)/libcharset \
$(LOCAL_PATH)/lib \
$(LOCAL_PATH)/libcharset/include \
$(LOCAL_PATH)/srclib

LOCAL_SHARED_LIBRARIES := libiconv //这里是引用libiconv.so动态库,
LOCAL_MODULE :=ubox
LOCAL_CFLAGS := -O0 -g
LOCAL_LDLIBS := -lpthread

include $(BUILD_EXECUTABLE)



编译时遇到的错误 libcharset/lib/localcharset.c:51:24: error: langinfo.h: No such file or directory

解决方法:

修改目录文件libcharset/config.h的宏定义,禁止该宏定义:

/* Define if you haveand nl_langinfo(CODESET). */

#define HAVE_LANGINFO_CODESET 0

报“c undeclaired”错误

解决方法:

修改文件/libcharset/lib/localcharset.c中函数get_charset_aliases (void)

搜索:int c;

把该变量定义放到该函数的开始处。


字符编码转换简单例子:

iconv_t iconv_open(const char *tocode, const char *fromcode);  

size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);  

int iconv_close(iconv_t cd);  

iconv_open函数用来打开一个编码转换的流,

iconv函数的作用是实际进行转换,

iconv_close函数的作用就是关闭这个流。

实际用法参见下面的例子,下面是一个将UTF-8码转换成GBK码的例子,我们假设已经有了一个uft8编码的输入缓冲区inbuf以及这个缓冲区的长度inlen。 

 iconv_t cd = iconv_open( "GBK", "UTF-8"); 

 char *outbuf = (char *)malloc(inlen * 4 ); 

 bzero( outbiuf, inlen * 4); 

 char *in = inbuf;  

char *out = outbuf; 

 size_t outlen = inlen *4; 

 iconv(cd, &in, (size_t *)&inlen, &out,&outlen); 

 outlen = strlen(outbuf); 

 printf("%s\n",outbuf); 

 free(outbuf); 

 iconv_close(cd);  

非常值得注意的地方是:iconv函数会修改参数in和参数out指针所指向的地方,也就是说,在调用iconv函数之前,

我们的in和inbuf指针以及out和outbuf指针指向的是同一块内存区域,但是调用之后out指针所指向的地方就不是outbuf了,

同理in指针。所以要  char *in = inbuf;  char *out = outbuf;


另存一下,使用或者释放内存的时候也要使用原先的那个指针outbuf和inbuf。

iconv -f GB2312 -t UTF-8 gb1.txt >gb2.txt 将gb1里的编码从GB2312转化成UTF-8 并重定向到gb2.txt


更多相关文章

  1. C语言函数的递归(上)
  2. Android开发——Android搜索框架
  3. Android(安卓)Activity 各函数解析
  4. android sdk 编译--如何将源代码加入android.jar,以及make原理 2
  5. android在代码中为new出的控件设置ID及setId()异常
  6. Android——打包篇:Android(安卓)Studio将代码打包成jar包
  7. 如何在Android下使用JNI
  8. Android(安卓)MVP设计模式实例详解
  9. Hack4-自定义PreferenceActivity界面

随机推荐

  1. mysql创建表的sql语句详细总结
  2. Windows 64位重装MySQL的教程(Zip版、解压
  3. mysql 悲观锁与乐观锁的理解及应用分析
  4. mysql 复制原理与实践应用详解
  5. mysql 数据库备份的多种实现方式总结
  6. mysql 的root 用户无法授权及解决navicat
  7. mysql的事务,隔离级别和锁用法实例分析
  8. mysql5.7 生成列 generated column用法实
  9. mysql8 公用表表达式CTE的使用方法实例分
  10. mysql中left join设置条件在on与where时