Android NDK使用Iconv进行编码转换

在使用ndk开发应用程序时,有时需要字符编码转换,这里使用开源库iconv进行字符编码转换,代码如下

#include <jni.h>
#include <string>
#include <iconv.h>
#include <iostream>

class HStringConverter
{
	char	*_buf;
	size_t	_bufSize;
public:
	HStringConverter()
		:_buf(nullptr), _bufSize(0)
	{}
	~HStringConverter()
	{
		delete [] _buf;
		_buf = nullptr;
		_bufSize = 0;
	}

	char *convertString(const char * fromCode, const char * toCode, const char * source)
	{
		size_t retlen = 0;
		size_t inbytesleft = strlen(source);
		if (!strncmp(fromCode, "UTF-16LE", 8))
		{
			inbytesleft = wcslen((wchar_t *)source) * 2;
		}
		size_t outbytesleft = inbytesleft * 4 + 2;
		retlen = outbytesleft;

		char *tmp = resize(outbytesleft);

		char * inbuf = (char *)source;
		char * outbuf = (char *)tmp;

		iconv_t cd = iconv_open(toCode, fromCode);
		size_t errorNo = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
		retlen -= outbytesleft;

		if (errorNo == -1)
		{
			memcpy(tmp, source, inbytesleft);
		}
		else
		{
			memset(tmp + retlen, 0, outbytesleft);
		}

		iconv_close(cd);

		return tmp;
	}
private:
	char *resize(int newSize) 
	{
		if (_bufSize < newSize)
		{
			delete [] _buf;
			_bufSize = newSize;
			_buf = new char[newSize];
		}
		memset(_buf, 0, newSize);
		return _buf;
	}
};
class GBK: public HStringConverter
{
	const char *_gbk;
public:
	GBK(const char *gbk)
		:_gbk(gbk)
	{ }
	char *toUtf8()
	{
		return convertString("GBK", "UTF-8", _gbk);
	}
	wchar_t *toUnicode()
	{
		return (wchar_t *)convertString("GBK", "UTF-16LE", _gbk);
	}
};
class Unicode: public HStringConverter
{
	const wchar_t *_unicode;
public:
	Unicode(const wchar_t *unicode)
		:_unicode(unicode)
	{
	}
	char *toGBK()
	{
		return convertString("UTF-16LE","GBK", (const char*)_unicode);
	}
	char *toUtf8()
	{
		return convertString("UTF-16LE","UTF-8", (const char*)_unicode);
	}
};
class Utf8: public HStringConverter
{
	const char *_utf8;
public:
	Utf8(const char *utf8)
		:_utf8(utf8)
	{}
	wchar_t *toUnicode()
	{
		return (wchar_t *)convertString("UTF-8", "UTF-16LE", _utf8);
	}
	char *toGBK()
	{
		return convertString("UTF-8", "GBK", _utf8);
	}
};

extern "C"
	jstring Java_com_irisking_attendserver_AttendServer_getName(JNIEnv *env, jobject thisz)
{
	const char *name = "韩呈杰";
	return env->NewStringUTF(GBK(name).toUtf8());
}

这里支持UTF-16LE(Unicode),UTF-8和GBK之间的编码相互转换。其中最后一个函数是使用示例。
Android NDK r9c中,iconv.h有一处bug,需修改后才可编译,否则在编译时会报错,修改如下:

//#ifdef __cplus_plus
//改为
#ifdef __cplusplus
}  // extern "C"
#endif

完整的源代码,参见: Android NDK使用Iconv进行编码转换
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值