1. 在VS中给项目附加依赖项里加入libiconv.lib
在VS“解决方案资源管理器”视图中——项目->属性->配置属性->连接器->输入->附加依赖项里填写“libiconv.lib”,多个lib以空格隔开(等同于“#pragma comment(lib, "libicon.lib")”语句)。
2.包含头文件iconv/iconv.h.,并通过这个库封装几个编码转换函数
代码如下:
.H文件:
/******************************************************************************* 处理和编码转码相关东西: 1. GBToUTF8用于将GB2312编码字符转成UTF-8编码字符,这样就不需要将文件设置成utf-8格式, 比如label->setString(GBToUTF8("暂停"))。 2. convert_info_str用于将一段文字(可含中文)中的标志符(默认为'X')用给定的参数列表中的值替换掉。比如: ParamValueList value_list; value_list << 2 << 30.528f << 3000 << "健康" << "A"; label->setString(ConvertInfoStr("玩家级别: X, 攻击力: X伤害/次, 金币数: X,状态:X, 评级: X", value_list)); 将显示 "玩家级别: 2, 攻击力: 30.528伤害/次, 金币数: 3000,状态:健康, 评级: A"。(注意此处不需要手动调用GBToUTF8了,会自动调用)。 默认替换的是字符串中的X,若字符串中恰好有不需要替换的X,则可以手动设置一个新的字符来作为标志字符, 比如以'?'来作为标志符: datas << 3 << 50 << 3 << 50 << (3 * 50); convert_info_str("技能书个数: ?, 每个技能书可卖: ?钻石,共可卖 ? X ? = ? 钻石", datas, '?'); 将返回: "技能书个数: 3, 每个技能书可卖: 50钻石,共可卖 3 X 50 = 150 钻石" 上面使用'?'作为标志字符。 *******************************************************************************/
#ifndef UTIL_ENCODEUTIL_H_ #define UTIL_ENCODEUTIL_H_
#include "cocos2d.h" #include "util/paramvaluelist.h"
namespace util {
// GB2312转UTF-8 const char *GBToUTF8(const char *str);
// 根据datas的个数将text里的同等个数的'X'(由先到后)替换成datas相应位置数字, // 返回转换后的string类型内容 // text: 带有至少datas.size()个'X'的字符串 // datas: 整数数组,这些数字将要从左到右替换掉text中对应的'X' const char *ConvertInfoStr(const char *text, const ParamValueList &value_list);
// 根据datas的个数将text里的同等个数的flag_char(由先到后)替换成datas相应位置数字, // 返回转换后的string类型内容 // text: 带有至少datas.size()个flag_char的字符串 // datas: 整数数组,这些数字将要从左到右替换掉text中对应的flag_char // flag_char: 需要被替换的字符 const char *ConvertInfoStr(const char *text, const ParamValueList &value_list, char flag_char);
}
#endif // UTIL_ENCODEUTIL_H_
|
.ccp文件
#include "util/encodeutil.h"
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) #include "iconv.h" #else //F:\TrunkGame\cocos2d-jijiafengbao\cocos2dx\platform\third_party\win32\iconv //#include "../../../iconv/include/iconv.h" #include "../../../iconv/include/iconv.h" #endif
#include "util/macroutil.h" using namespace std; USING_NS_CC;
#ifdef WIN32 #pragma comment(lib, "libiconv.lib") #endif
namespace util {
// 默认的标志字符 const char kDefaultFlagChar = 'X'; #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) //const char *GBToUTF8(const char *str) { // const char *result_str = ""; // iconv_t iconv_h; // iconv_h = iconv_open("utf-8", "gb2312"); // if (iconv_h != 0) { // const char* str_char = (char*)str; // const char** pin = &str_char; // size_t str_len = strlen(str_char); // char* outbuf = (char*) malloc(str_len*4); // char* p_buff = outbuf; // memset(outbuf, 0, str_len * 4); // size_t out_len = str_len * 4; // if (iconv(iconv_h, pin, &str_len, &outbuf, &out_len) != -1) { // result_str = str_format("%s", p_buff); // } else { // CCAssert(false, ""); // } // iconv_close(iconv_h); // } else { // CCAssert(false, ""); // } // return result_str; //}
static char g_GBKConvUTF8Buf[1024*2] = {0};
const char* GBToUTF8(const char *strChar) {
iconv_t iconvH; iconvH = iconv_open("UTF-8//IGNORE","GBK"); if (iconvH == 0) return "?"; size_t strLength = ::strlen(strChar); size_t outLength = strLength<<2; size_t copyLength = outLength; ::memset(g_GBKConvUTF8Buf, 0, 1024*2);
char* outbuf = (char*) ::malloc(outLength); char* pBuff = outbuf; ::memset( outbuf, 0, outLength); //兲使嘚靈魂 if (-1 == iconv(iconvH, &strChar, &strLength, &outbuf, &outLength)) { iconv_close(iconvH); ::free(pBuff); return "?"; } ::memcpy(g_GBKConvUTF8Buf,pBuff,copyLength); ::free(pBuff); iconv_close(iconvH); return g_GBKConvUTF8Buf; }
#endif
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID) #include "../../../iconv/include/iconv.h" #define UTEXT(str) GBKToUTF8(str) #define GTEXT(str) UTF8ToGBK(str) static char g_GBKConvUTF8Buf[1024*2] = {0};
const char* UTF8ToGBK(const char *strChar) { iconv_t iconvH; //iconvH = iconv_open("UTF-8//IGNORE","gb2312"); iconvH = iconv_open("GBK","UTF-8"); if (iconvH == 0) return "?"; size_t strLength = ::strlen(strChar); size_t outLength = strLength<<2; size_t copyLength = outLength; ::memset(g_GBKConvUTF8Buf, 0, 1024*2);
char* outbuf = (char*) ::malloc(outLength); char* pBuff = outbuf; ::memset( outbuf, 0, outLength); //兲使嘚靈魂 if (-1 == iconv(iconvH,(char **) &strChar, &strLength, (char **)&outbuf, &outLength)) { iconv_close(iconvH); ::free(pBuff); return "?"; } ::memcpy(g_GBKConvUTF8Buf,pBuff,copyLength); ::free(pBuff); iconv_close(iconvH); return g_GBKConvUTF8Buf; } const char* GBToUTF8(const char *strChar) { iconv_t iconvH; iconvH = iconv_open("UTF-8","GBK"); if (iconvH == 0) { return "?"; } size_t strLength = ::strlen(strChar); size_t outLength = strLength<<2; size_t copyLength = outLength; ::memset(g_GBKConvUTF8Buf, 0, 1024*2);
char* outbuf = (char*) ::malloc(outLength); char* pBuff = outbuf; ::memset( outbuf, 0, outLength);
if (-1 == iconv(iconvH,(char **) &strChar, &strLength, (char **)&outbuf, &outLength)) { iconv_close(iconvH); return "?"; } ::memcpy(g_GBKConvUTF8Buf,pBuff,copyLength); ::free(pBuff); iconv_close(iconvH); return g_GBKConvUTF8Buf; } #endif
const char *ConvertInfoStr(const char *text, const ParamValueList &value_list) { return ConvertInfoStr(text, value_list, kDefaultFlagChar); }
const char *ConvertInfoStr(const char *text, const ParamValueList &value_list, char flag_char) { string result = text; const list<string> ¶m_value_list = value_list.value_list(); for (list<string>::const_iterator value_iter = param_value_list.begin(); value_iter != param_value_list.end(); ++value_iter) { const string::size_type kFlagCharPos = result.find(flag_char); CCAssert(kFlagCharPos != string::npos, ""); result.replace(kFlagCharPos, 1, *value_iter); } return GBToUTF8(result.c_str()); }
}
|
|
4.将Win32项目移植到Android上
Cocos2D-X自带有win32上的iconv库,但是Android需要的不同,需要自行编译。这里提供一个已编译好的iconv库:http://download.youkuaiyun.com/detail/yupingliu/5842299
下载成功后,将解压后的库文件放在cocos2d-x-2.1.4的根目录下
在新建的Android项目中(如何新建Cocos2D-X的Android项目),打开该目录下的pro.android/jni文件下的Android.mk文件(推荐使用UltraEdit,而不用windows自带的记事本)。修改如下:添加如下代码
\
LOCAL_C_INCLUDES +=$(LOCAL_PATH)/../../../iconv/include
LOCAL_SHARED_LIBRARIES :=libiconv
\
$(call import-module,iconv)
但是,尽管以上操作可以使Android项目在cygwin下编译时不会出错,但在eclipse上调试的时候,中文并不会显示出来。
目前我也没有找到原因,如果有读者有更好的解决方案,望分享,谢谢啦~~
如果想在Android项目上显示中文,目前的方法是:牺牲VS为显示中文乱码(不使用iconv库),把对应的CPP文件另存为utf-8编码格式(详见上述第三点),使用普通的设置文本的方法(如CCLabelTTF* scoreIndicator = CCLabelTTF::create("分数", "Arial", 20);)。
这样,尽管在win32下是乱码,但是在android平台上还是可以显示中文了。
5.常见的编译错误
如果读者仍然想使用iconv,在VS上成功显示中文字符,在做了第二步后,使用cygwin交叉编译将win32项目移植到android上时,可能会出现如下错误:
1.fatal error: iconv\iconv.h: No such file or directory
解决方案:将E:\cocos2d-x-2.1.4\cocos2d-x-2.1.4\(对应你的Cocos2D-X根目录)cocos2dx\platform\third_party\win32目录下的iconv文件夹复制到cocos2d-x-2.1.4根目录下的projects文件夹里你的项目中的pro.win文件夹里。
注意:是放在你引用了“iconv/iconv.h”的文件同目录下,这里我是在Tool.h里“#include "iconv/iconv.h"”,所以我讲iconv文件夹复制到了Tool.h同目录下。
如果是cocos2d3.X版本。
注意点:检查iconv文件夹的完整,项目中如果一些字体没有的话,打包到手机上面会直接挂
将iconv文件拷贝至 iconv_text/cocos2d文件目录下面和win32文件目录下
MK文件内容: