首页 > 代码库 > Cocos2d-x中关于lua的坑

Cocos2d-x中关于lua的坑

上周在项目开发中遇到一个奇怪的问题,某个c++模块解压完的字节流数据传递给lua后,lua在做基于字节流的反序列化时始终出错,刚开始以为是不是c++模块读取出来的字节流有问题,但是debug发现,c++拿到的字节流确实是正确的,于是跑到lua的接口中打印了字节流的内容和长度发现,在某些情况下C++中打印出来的字节流和lua拿到的字节流的长度不等,突然想起可能是lua和C++对string的支持不同导致的.因为C++中没有字节这个类型,所以存储字节流就一般存储到以char类型结构为基础类型的数组或者std::string中,但是这时,如果对char数组或者std::string进行strlen类似的操作,则会存在隐患,因为strlen认为遇到‘\0‘字节就结束了,而如果存储在char数组中的字节流恰好是中间含有‘\0‘这个字节的话,则得出来的长度就有问题了;但是在lua中,string中含有‘\0‘是不会有问题的, 因为它求长度并不是简单的调用strlen,而是lua自己实现了strlen函数, 所以即使是拿到含有‘\0‘字符的字节流字符串, 也不会出现错误.

进过调试,发现确实是这里的问题,于是更改了cocos2d-x中 CCLuaStack中pushCCLuaValue函数中的代码即解决了上述问题,代码如下(注意注释的部分, 被注释的部分为cocos2d-x原来的代码):

void CCLuaStack::pushCCLuaValue(const CCLuaValue& value)
{
    const CCLuaValueType type = value.getType();
    if (type == CCLuaValueTypeInt)
    {
        return pushInt(value.intValue());
    }
    else if (type == CCLuaValueTypeFloat)
    {
        return pushFloat(value.floatValue());
    }
    else if (type == CCLuaValueTypeBoolean)
    {
        return pushBoolean(value.booleanValue());
    }
    else if (type == CCLuaValueTypeString)
    {
        return pushString(value.stringValue().c_str(), value.stringValue().length());
//        return pushString(value.stringValue().c_str()); cocos2dx的bug
    }
    else if (type == CCLuaValueTypeDict)
    {
        pushCCLuaValueDict(value.dictValue());
    }
    else if (type == CCLuaValueTypeArray)
    {
        pushCCLuaValueArray(value.arrayValue());
    }
    else if (type == CCLuaValueTypeCCObject)
    {
        pushCCObject(value.ccobjectValue(), value.getCCObjectTypename().c_str());
    }
}