上周在项目开发中遇到一个奇怪的问题,某个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()); } }
Cocos2d-x中关于lua的坑,布布扣,bubuko.com
原文地址:http://my.oschina.net/pigsoldier/blog/287792