Cocos2d-x使用iconv库解决UTF8乱码与移植安卓

时间:2021-09-12 08:40:56

在windows平台上使用VS开发Cocos游戏,会用到字符转码,将字符从GBK转到UTF8,转码需要用到iconv库。在这里分享一下。

下面是用来转码的头文件和cpp文件:、

CodeConversion.h

#ifndef _H_CODECONVERSION_H_
#define _H_CODECONVERSION_H_

#include "cocos2d.h"
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "win32-specific/icon/include/iconv.h"
#else
#include "../cocos2d/libiconv/include/iconv.h"
#endif

USING_NS_CC;

namespace CodeConversion {
    int code_convert(const char *from_charset, const char *to_charset, const char *inbuf, size_t inlen, char *outbuf, size_t outlen);

    // UTF8转为GB2312
    std::string utfToGb(const char *inbuf);
    // GB2312转为UTF8
    std::string gbToUtf(const char *inbuf);
};

#endif 

CodeConversion.cpp

#include "CodeConversion.h"

int CodeConversion::code_convert(const char *from_charset, const char *to_charset, const char *inbuf, size_t inlen, char *outbuf, size_t outlen)
{
    iconv_t cd;
    cd = iconv_open(to_charset,from_charset);
    if(cd==0) return -1;

    const char *temp = inbuf;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
    char ** pin = const_cast<char**>(&temp);
#else
    const char **pin = &temp;
#endif
    char **pout = &outbuf;
    memset(outbuf,0,outlen);
    if(iconv(cd,pin,&inlen,pout,&outlen)==-1)
    {
        iconv_close(cd);
        return -1;
    }
    iconv_close(cd);
    return 0;
}

/*UTF8转为GBK*/
std::string CodeConversion::utfToGb(const char *inbuf)
{
    size_t inlen = strlen(inbuf);
    char * outbuf = new char[inlen * 2 + 2];
    std::string strRet;
    if(code_convert("utf-8", "gbk//IGNORE", inbuf, inlen, outbuf, inlen * 2 + 2) == 0)
    {
        strRet = outbuf;
    }
    delete [] outbuf;
    return strRet;
}

/*GBK转为UTF8*/
std::string CodeConversion::gbToUtf(const char *inbuf)
{
    size_t inlen = strlen(inbuf);
    char * outbuf = new char[inlen * 2 + 2];
    std::string strRet;
    if(code_convert("gbk", "utf-8//IGNORE", inbuf, inlen, outbuf, inlen * 2 + 2) == 0)
    {
        strRet = outbuf;
    }
    delete [] outbuf;
    return strRet;
}

上面的代码可以直接使用。
注意win32版本的路径和安卓版本的路径不同,
win32用的是cocos引擎自带的,在项目的cocos2d\external\win32-specific\icon路径下面,但是 安卓版本的库 需要自己下载,然后放到项目的某个路径下面,这里我是放到了cocos2d文件夹下面,和external、extensions等同级。

#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
#include "win32-specific/icon/include/iconv.h"
#else
#include "../cocos2d/libiconv/include/iconv.h"
#endif

接下来就是移植安卓。
修改项目的 proj.android\jni 目录下的 Android.mk,下面是我的 Android.mk,可以参考下

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

$(call import-add-path,$(LOCAL_PATH)/../../cocos2d)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/external)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/cocos)

LOCAL_MODULE := cocos2dcpp_shared

LOCAL_MODULE_FILENAME := libcocos2dcpp

FILE_LIST := hellocpp/main.cpp
FILE_LIST += $(wildcard $(LOCAL_PATH)/../../Classes/*.cpp)
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes \
$(LOCAL_PATH)/../../cocos2d/libiconv/include \
$(LOCAL_PATH)/../../cocos2d/libiconv/libcharset \
$(LOCAL_PATH)/../../cocos2d/libiconv/lib \
$(LOCAL_PATH)/../../cocos2d/libiconv/libcharset/include \
$(LOCAL_PATH)/../../cocos2d/libiconv/srclib \
$(LOCAL_PATH)/../../cocos2d/libiconv \

# _COCOS_HEADER_ANDROID_BEGIN
# _COCOS_HEADER_ANDROID_END


LOCAL_STATIC_LIBRARIES := cocos2dx_static
LOCAL_STATIC_LIBRARIES += libiconv_static

# _COCOS_LIB_ANDROID_BEGIN
# _COCOS_LIB_ANDROID_END

include $(BUILD_SHARED_LIBRARY)

$(call import-module,.)
$(call import-module,libiconv)

# _COCOS_LIB_IMPORT_ANDROID_BEGIN
# _COCOS_LIB_IMPORT_ANDROID_END

注意:LOCAL_STATIC_LIBRARIES += libiconv_static 里面的 libiconv_static 和 $(call import-module,libiconv) 里面的 libiconv 不是随便来的,在下载好的iconv库文件夹里面有个Android.mk 文件,打开可以看到里面有下面两句:

LOCAL_MODULE := libiconv_static
LOCAL_MODULE_FILENAME := libiconv

就是从这里来的。

然后交叉编译应该就没问题了,我是没碰到问题。希望能帮到大家。