Cocos 2 d-xにおけるluaに関するピット
1825 ワード
先週、プロジェクト開発で奇妙な問題に遭遇しました.ある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'文字を含むバイトストリーム文字列を取得してもエラーは発生しない.
デバッグを行ったところ、確かにここの問題であることが判明し、cocococos 2 d-xにおけるCCLuaStackにおけるpushCCLuaValue関数のコードを変更すると上記の問題が解決し、コードは以下の通りである(注釈の部分に注意し、注釈された部分はcococos 2 d-xの元のコードである):
デバッグを行ったところ、確かにここの問題であることが判明し、cocococos 2 d-xにおけるCCLuaStackにおけるpushCCLuaValue関数のコードを変更すると上記の問題が解決し、コードは以下の通りである(注釈の部分に注意し、注釈された部分はcococos 2 d-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());
}
}