展会信息港展会大全

关于cocos2dx中文转UTF8码的解决方案
来源:互联网   发布日期:2015-09-28 10:37:44   浏览:1967次  

导读: cocos2dx支持中文显示,只要将中文字符转换成UTF-8字符集就可以正常显示,不过在实践上还是会出现很多问题会困扰开发者。 通常来说,目前的解决方案有以下几种: 1、把代码文件(.h/...

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

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;

} .h>

其次,就是转换函数代码如下: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码的解决方案

赞助本站

人工智能实验室
AiLab云推荐
展开

热门栏目HotCates

Copyright © 2010-2024 AiLab Team. 人工智能实验室 版权所有    关于我们 | 联系我们 | 广告服务 | 公司动态 | 免责声明 | 隐私条款 | 工作机会 | 展会港