关于cocos2dx中文转UTF8码的解决方案

转载请注明出处:帘卷西风的专栏(http://blog.csdn.net/ljxfblog)

cocos2dx支持中文显示,只要将中文字符转换成UTF-8字符集就可以正常显示,不过在实践上还是会出现很多问题会困扰开发者。

通常来说,目前的解决方案有以下几种:

1、把代码文件(.h/.cpp/.lua等)的文件编码格式改成UTF-8格式即可,这对于单机游戏来说是很好的解决方案。但是对于服务器传过来的文字则无能为力。

2、使用iconv库来做转换,使用接口比较简单,win32版本也能直接用上,但是在安卓上面就需要自己编译整合iconv的源码,没做过的有一些难度。

3、自立更生,自己写代码来实现。

本文主要讲第三种方案,第二种方案其实也不错,但是更折腾一点,以后有时间在来折腾。

自己写转utf-8的接口,主要需要考虑以下几个问题。主要都是跨平台的问题。

1、在win32下面,很简单也很容易实现,因为win32API已经帮我们提供了相关的接口(WideCharToMultiByte /MultiByteToWideChar等),只需要稍微处理一下即可。相关代码如下:

const char* gb23122utf8(const char* gb2312)    
{  
	int len = MultiByteToWideChar(0, 0, gb2312, -1, NULL, 0);    
	wchar_t* wstr = new wchar_t[len+1];    
	memset(wstr, 0, len+1);    
	MultiByteToWideChar(0, 0, gb2312, -1, wstr, len);    
	len = WideCharToMultiByte(65001, 0, wstr, -1, NULL, 0, NULL, NULL);    
	char* str = new char[len+1];
	memset(str, 0, len+1);    
	WideCharToMultiByte(65001, 0, wstr, -1, str, len, NULL, NULL);    
	if(wstr) delete[] wstr;    
	return str;
}  

2、在安卓平台,就稍微麻烦一点。首先考虑的是,c语言有和win32接口相似的接口(mbstowcs/wcstombs等),按这种方案,需要使用setlocale这个接口,经过测试发现,这个接口在windows和linux都有效,能正确转成utf-8码,但是在安卓上这个接口无效,始终返回NULL,所以不能使用mbstowcs/wcstombs。后来辗转查了一些资料,决定使用icu库,这个库在大部分安卓机器上都有,只是版本不一样,但是还是能够正确转,姑且暂时使用这种苟且的方案吧,以后再使用高大上的方案。具体代码如下:

首先是需要找到icu库中的接口函数地址:

#include <dlfcn.h>
void (*ucnv_convert)(const char *, const char *, char * , int32_t , const char *, int32_t,int32_t*) = 0;
bool openIcuuc()
{
	void* libFile = dlopen("/system/lib/libicuuc.so", RTLD_LAZY); 
	if (libFile)
	{
		ucnv_convert = (void (*)(const char *, const char *, char * , int32_t , const char *, int32_t,int32_t*))dlsym(libFile, "ucnv_convert_3_8");

		int index = 0;
		char fun_name[64];
		while (ucnv_convert == NULL)
		{
			sprintf(fun_name, "ucnv_convert_4%d", index++);
			ucnv_convert = (void (*)(const char *, const char *, char * , int32_t , const char *, int32_t,int32_t*))dlsym(libFile, fun_name);
			if (ucnv_convert) 
				return true;				
			if (++index > 11) 
				break;
		}
		dlclose(libFile);
	}
	return false;
} 

其次,就是转换函数代码如下:

const char* gb23122utf8(const char * gb2312)
{
	if (ucnv_convert == NULL)
	{
		openIcuuc();
	}		
	if (ucnv_convert)
	{
		int err_code = 0;
		int len = strlen(gb2312);
		char* str = new char[len * 2 + 10];    
		memset(str, 0, len * 2 + 10);
		ucnv_convert("utf-8", "gb2312", str, len * 2 + 10, gb2312, len, &err_code);
		if (err_code == 0)
		{
			return str;
		}
	}
	char test[256] = "gb23122utf8 error";
	char* str = new char[30]; 
	strcpy(str, test);
	return str;
}

好了,这就大功告成了,在几台安卓机上测试都OK,但是在模拟器上失败,可能是缺少库的问题。

当然如果有需要可以把这个接口暴露给lua使用。

static int luaA_Strg2u(lua_State *L)
{
	const char* gb2312 = luaL_checkstring(L, 1);
	const char* utf8 = gb23122utf8(gb2312);
	lua_pushstring(L, utf8);
	delete [] utf8;
	return 1;
}

void registerLuaFunction(lua_State* luaState)
{
	lua_register(luaState, "strg2u", luaA_Strg2u);	
	tolua_api4lua_open(luaState);
}

最后把我封装的文件分享给大家吧!

关于cocos2dx中文转UTF8码的解决方案

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏搜云库

Spring Boot 中使用 MongoDB 增删改查

本文快速入门,MongoDB 结合SpringBoot starter-data-mongodb 进行增删改查

65270
来自专栏阿北的知识分享

yii2开发中19条推荐实践

这个是做yii2开发的基石,除非没有办法使用,否则请不要放弃,除了更容易的安装yii2及第三方扩展外,能使用Composer代表着你的服务器最少能运行起来php...

43660
来自专栏漏斗社区

代码审计| 从今天起,做一个精致的多米咖!

0x00 背景 在看CNVD漏洞库的时候发现有师傅发了某cms前台SQL注入漏洞,通过查阅漏洞描述可知道存在问题的参数是cardpwd,便开始尝试对该版本的c...

37580
来自专栏木子昭的博客

用wepy制作简易签名板

23130
来自专栏涤生的博客

天池中间件大赛——单机百万消息队列存储设计与实现

这次天池中间件性能大赛初赛和复赛的成绩都正好是第五名,本次整理了复赛《单机百万消息队列的存储设计》的思路方案分享给大家,实现方案上也是决赛队伍中相对比较特别的。

25410
来自专栏Java 源码分析

Netty 入门

1. 粘包问题 一 .长连接与短连接: 1.长连接:Client方与Server方先建立通讯连接,连接建立后不断开, 然后再进行报文发送和接收。长连接在 net...

40870
来自专栏FreeBuf

从远程桌面服务到获取Empire Shell

本文将为大家详细介绍如何在只能访问远程桌面服务,且有 AppLocker 保护 PowerShell 处于语言约束模式下获取目标机器 Empire shell。...

20040
来自专栏24K纯开源

用Qt写软件系列二:QCookieViewer(浏览器Cookie查看器)

预备     继上篇《浏览器缓存查看器QCacheViewer》之后,本篇开始QCookieViewer的编写。Cookie技术作为网站收集用户隐私信息、分析用...

29060
来自专栏程序员的SOD蜜

单数据库,多数据库,单实例,多实例不同情况下的数据访问效率测试

最近公司的项目准备优化一下系统的性能,希望在数据库方面看有没有提升的空间,目前压力测试发现数据库服务器压力还不够大,Web服务器压力也不是很大的情况下,前台页面...

275100
来自专栏杨建荣的学习笔记

MySQL频繁停库的问题分析(r12笔记第33天)

最近也抽空帮一些网友解决一些问题,有些是Oracle,有些是MySQL,有时候虽然忙忙乎乎,但是解决问题之后还是很有成就感的。 今天来说一个蛮有意思的问...

589100

扫码关注云+社区

领取腾讯云代金券