Android之NDK编码转(UTF8->GBK)

基于NDK下的编码转换,当然是直接调用C/C++下的实现效率更高,下面介绍2种方案(不建议通过JNI调用JAVA的实现,尽管这样也能实现编码的转换)。

1. 采用Android系统自带的libicuuc.so库,此库的源代码在/home/george/source/rk3168_v4.2/external/icu4c/common下

2. 采用第三方编码转换库libiconv,源码链接:http://ftp.gnu.org/pub/gnu/libiconv/

libiconv的使用有3个函数:
a) iconv_t iconv_open (const char* tocode, const char* fromcode);
b) size_t iconv (iconv_t cd, const char* * inbuf , size_t * inbytesleft, char* * outbuf , size_t * outbytesleft);
inbytesleft:inbuf的字符串长度;
outbytesleft:输入为outbuf所指向的缓冲区长度,输出为剩余没用到的缓冲区长度;因此转换后的字符串长度为(outbuflen - outbytesleft);
inbuf, outbuf:返回时指针都后移了,需要注意。
c) int iconv_close (iconv_t cd);

这里采用Android系统自带的库进行编码转换,当然也可采用第三方支持。以下贴出代码段

(gbk和Unicode的互转因为没有用到,所以未贴出,但我想你应该要会了吧):


#include "libcnv.h"
/* use dl API include file */
#include <dlfcn.h>

/* typedef a function pointer to pointer ucnv_convert method */
/*
see the source code define
int32_t ucnv_convert(const char *toConverterName, const char *fromConverterName,
     char *target, int32_t targetSize,
     const char *source, int32_t sourceSize,
     int32_t * err)
*/

typedef int32_t (*TUCNVCONVERT)(
								const char *lpcOutEcd, 
								const char *lpcInEcd, 
								char* lpOutBuf, 
								int32_t nOutBufLen,
								const char* lpcInStr, 
								int32_t nInStrLen, 
								int32_t *pnErrCode);
/* pointer libicuuc.so dl lib */
static void* g_lpdlIcuuc = 0;

/* ucnv_convert method pointer */
static TUCNVCONVERT g_lpfnUcnvConvert = 0;

//在libicuuc.so中找到函数ucnv_convert
int dl_icuuc_init()
{
	g_lpfnUcnvConvert = 0;
	g_lpdlIcuuc = dlopen("/system/lib/libicuuc.so", RTLD_LAZY);
	if (g_lpdlIcuuc != 0)
	{
		int i, j;
		char szDLFnName[32] = {0};
		i = 3;
		j = 8;
		//android2.1, ucnv_convert_3_8
		//android2.2, ucnv_convert_4_2
		//android2.3, ucnv_convert_44
		//android4.0, ucnv_convert_46
		//android4.0, ucnv_convert_46
		//android4.1, ucnv_convert_47
		//android4.2, ucnv_convert_48
		//android4.3, ucnv_convert_50
		//android4.4, ucnv_convert_51
		//其尾椎在,在源码的common/unicode/uvernum.h:77:  #define U_ICU_VERSION_SUFFIX _48

		g_lpfnUcnvConvert = (TUCNVCONVERT)dlsym(g_lpdlIcuuc, "ucnv_convert_3_8");
		while (0 == g_lpfnUcnvConvert)
		{
			memset(szDLFnName, 0, 32 * sizeof(char));
			sprintf(szDLFnName, "ucnv_convert_%d%d", i, j);
			g_lpfnUcnvConvert = (TUCNVCONVERT)dlsym(g_lpdlIcuuc, szDLFnName);
			if (g_lpfnUcnvConvert != 0)
			{
				return 1;
			}
			sprintf(szDLFnName, "ucnv_convert_%d_%d", i, j);
			g_lpfnUcnvConvert = (TUCNVCONVERT)dlsym(g_lpdlIcuuc, szDLFnName);
			if (g_lpfnUcnvConvert != 0)
			{
				return 1;
			}
			j++;
			if (j > 9)
			{
				j = 1;
				i++;
				if (i > 5)
				{
					break;
				}
			}
		}
	}
	return 0;
}

int dl_icuuc_uninit()
{
	if (g_lpdlIcuuc != 0)
	{
		dlclose(g_lpdlIcuuc);
		g_lpdlIcuuc = 0;
	}
	return 1;
}

//utf-8,gb2312,ucs4
//utf-8:  一个英文字母或者是数字占用一个字节,汉字占3个字节
//gb2312: 一个英文字母或者是数字占用一个字节,汉字占2个字节
int32_t dl_icuuc_gbk2utf8(
						  char *outbuf, int32_t buflen, const char *instring, int32_t inlen)
{
	int32_t iret;
	iret = 0;
	if (outbuf != 0 && instring != 0)
	{
		if (g_lpfnUcnvConvert != 0)
		{
			int32_t err_code = 0;
			iret = g_lpfnUcnvConvert(
				"utf-8", "gb2312", outbuf, buflen, instring, inlen, &err_code);
		}
	}

	return iret;
}

int32_t dl_icuuc_utf82gbk(char *outbuf, int32_t buflen, const char *instring, int32_t inlen)
{
	int32_t iret;
	iret = 0;
	if (outbuf != 0 && instring != 0)
	{
		if (g_lpfnUcnvConvert != 0)
		{
			int32_t err_code = 0;
			iret = g_lpfnUcnvConvert(
				"gb2312", "utf-8", outbuf, buflen, instring, inlen, &err_code);
		}
	}

	return iret;
}

int32_t dl_icuuc_unicode2utf8(char *outbuf, int32_t buflen, const unsigned short *instring, int32_t inlen)
{
	int32_t iret;
	iret = 0;
	if (outbuf != 0 && instring != 0)
	{
		if (g_lpfnUcnvConvert != 0)
		{
			int32_t err_code = 0;
			iret = g_lpfnUcnvConvert(
				"utf-8", "ucs4", outbuf, buflen, (const char *)instring, 
				inlen*sizeof(unsigned short)/sizeof(char), &err_code);
		}
	}

	return iret;
}

int32_t dl_icuuc_utf82unicode(unsigned short *outbuf, int32_t buflen, const char *instring, int32_t inlen)
{
	int32_t iret;
	iret = 0;
	if (outbuf != 0 && instring != 0)
	{
		if (g_lpfnUcnvConvert != 0)
		{
			int32_t err_code = 0;
			iret = g_lpfnUcnvConvert(
				"ucs4", "utf-8", (char *)outbuf, 
				buflen*sizeof(unsigned short)/sizeof(char), 
				instring, inlen, &err_code);
		}
	}

	return iret;
}

转自:http://blog.csdn.net/longtian635241/article/details/41224719

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值