关于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等),只需要稍微处理一下即可。相关代码如下:

  1. constchar*gb23122utf8(char*gb2312)
  2. {
  3. intlen=MultiBytetoWideChar(0,gb2312,-1,NULL,0);
  4. wchar_t*wstr=newwchar_t[len+1];
  5. memset(wstr,len+1);
  6. MultiBytetoWideChar(0,wstr,len);
  7. len=WideCharToMultiByte(65001,NULL);
  8. char*str=char[len+1];
  9. memset(str,248)"> WideCharToMultiByte(65001,str,len,NULL);
  10. if(wstr)delete[]wstr;
  11. returnstr;
  12. }

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

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

copy
    #include<dlfcn.h>
  1. void(*ucnv_convert)(char*,boolopenIcuuc()
  2. void*libFile=dlopen("/system/lib/libicuuc.so",RTLD_LAZY);
  3. if(libFile)
  4. {
  5. ucnv_convert=(void(*)("ucnv_convert_3_8");
  6. intindex=0;
  7. charfun_name[64];
  8. while(ucnv_convert==NULL)
  9. sprintf(fun_name,"ucnv_convert_4%d",index++);
  10. ucnv_convert=(if(ucnv_convert)
  11. returntrue;
  12. if(++index>11)
  13. break;
  14. }
  15. dlclose(libFile);
  16. false;
  17. }

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

copy
    if(ucnv_convert==NULL)
  1. openIcuuc();
  2. if(ucnv_convert)
  3. interr_code=0;
  4. intlen=strlen(gb2312);
  5. char[len*2+10];
  6. memset(str,len*2+10);
  7. ucnv_convert("utf-8","gb2312",len*2+10,&err_code);
  8. if(err_code==0)
  9. }
  10. chartest[256]="gb23122utf8error";
  11. char[30];
  12. strcpy(str,test);
  13. }
好了,这就大功告成了,在几台安卓机上测试都OK,但是在模拟器上失败,可能是缺少库的问题。

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

copy
    staticintluaA_Strg2u(lua_State*L)
  1. char*gb2312=luaL_checkstring(L,1);
  2. char*utf8=gb23122utf8(gb2312);
  3. lua_pushstring(L,utf8);
  4. delete[]utf8;
  5. return1;
  6. voidregisterLuaFunction(lua_State*luaState)
  7. lua_register(luaState,"strg2u",luaA_Strg2u);
  8. tolua_api4lua_open(luaState);
  9. 最后把我封装的文件分享给大家吧!
    文件名:GB23122Utf8.h

    copy

      #ifndef__GB23122Utf8_H_
    1. #define__GB23122Utf8_H_
    2. #if(CC_TARGET_PLATFORM==CC_PLATFORM_WIN32)
    3. #endif
    4. #if(CC_TARGET_PLATFORM==CC_PLATFORM_ANDROID)
    5. #include<dlfcn.h>
    6. boolopenIcuuc()
    7. if(libFile)
    8. "ucnv_convert_3_8");
    9. intindex=0;
    10. charfun_name[64];
    11. while(ucnv_convert==NULL)
    12. sprintf(fun_name,index++);
    13. true;
    14. if(++index>11)
    15. break;
    16. dlclose(libFile);
    17. false;
    18. char*gb2312)
    19. if(ucnv_convert==NULL)
    20. openIcuuc();
    21. interr_code=0;
    22. intlen=strlen(gb2312);
    23. char[len*2+10];
    24. ucnv_convert("utf-8",&err_code);
    25. if(err_code==0)
    26. returnstr;
    27. chartest[256]="gb23122utf8error";
    28. char[30];
    29. strcpy(str,test);
    30. #endif
    31. #if(CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
    32. returngb2312;
    33. #endif//__GB23122Utf8_H_

    相关文章

        本文实践自 RayWenderlich、Ali Hafizji 的文章《...
    Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@1...
    第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从C...
        Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发...
    1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《...
       Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试...