上周在项目开发中遇到一个奇怪的问题,某个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