This problem was first discovered in Quick-x because it is wrong to add a Lua custom method for CCNode:
Function CCNode:myMethod ()
end
The run error prompt is [LUA error] stack overflow. When running on Player, even if the exception prompt box is thrown directly, the program must be closed directly.
The results of further debugging are as follows:
1. This problem only appears in exported subclasses. For example, there is no problem with CCObject, but all classes that inherit CCObject have problems, including CCNode.
2. The problem is not only the newly added methods, but also the newly added member variables.
So this problem can be described as: a C++ subclass exported by tolua++, and no new members can be added in lua.
Second, the analysis of the problem
Because it is impossible to add new members, the first thing to consider is whether there is a problem with the __newindex meta method.
Analyzing the code of tolua++, we can see that in the function of tolua_classevents, the function of __newindex is set to the function of class_newindex_event:
1
2
three
four
five
six
seven
eight
nine
10
1 1
12
13
14
Static int class _ new index _ event (Lua _ state * l)
{
int t = lua_type(L, 1);
If (t == LUA data)
{
//The code is omitted here.
}
Else if(t = = LUA _ table)
{
module _ new index _ event(L);
}
Returns 0;
}
When a new member is added to CCObject and its subclasses, where the value of t is LUA_TTABLE, the module_newindex_event function is called:
1
2
three
four
five
six
seven
eight
nine
10
1 1
12
13
14
15
16
17
18
19
20
2 1
22
23
24
25
Static int module _ new index _ event (Lua _ state * l)
{
lua_pushstring(L,"。 set”);
lua_rawget(L,-4);
if (lua_istable(L,- 1))
{
//The code is omitted here.
}
/* Call the old newindex meta event */
if (lua_getmetatable(L, 1)& amp; & amplua_getmetatable(L,- 1))
{
lua_pushstring(L," _ _ new index ");
lua_rawget(L,-2);
if (lua_isfunction(L,- 1))
{
lua_pushvalue(L, 1);
lua_pushvalue(L,2);
lua_pushvalue(L,3);
lua_call(L,3,0);
}
}
lua_settop(L,3);
lua_rawset(L,-3);
Returns 0;
}
You can see that this is. Set up tables in meta tables and assign new members.
The first judgment, neither CCObject nor its subclasses will enter, and it has no influence.
But the second judgment is different. CObject will not enter, but its subclasses will. From the point of code writing, it seems that we want to call the __newindex of its parent class here, but this is very problematic.
First of all, you still get the subclass's own __newindex, so you will call the class_newindex_event function again, and the class_newindex_event will naturally call the module_newindex_event, and the result will return to this code! In this way, the function is called recursively and endlessly until the stack overflows, which is why the error is the cause of the stack overflow.
Secondly, what I don't understand is that even the __newindex of the parent class seems to be unnecessary to be called here. Because if a subclass defines a new member to take effect in the parent class, then the problem is big. So I think it should be enough to call lua_rawset directly here.
Three. Temporary solution
Based on the above analysis, I think the problem lies in the handling of module_newindex_event. I tried to assign a new member directly without calling module_newindex_event, that is, the relevant code for modifying the class_newindex_event function is as follows:
1
2
three
four
five
six
Else if(t = = LUA _ table)
{
//module _ new index _ event(L);
lua_settop(L,3);
lua_rawset(L,-3);
}
The modified two sentences are equivalent to directly calling rawset to assign values to new members in lua.
After modification, run the following code in Lua:
Function CCNode:testFunc ()
Print now ("-CCNode.testFunc-Entry! ! !" )
end
Function MainScene:ctor ()
local s = display . news write(" logo . png ",display.cx,display.cy)
self:addChild
s:testFunc()
end
The above code can run normally and get the expected output.
But at present, this is only a temporary plan. I wonder if tolua++ wrote the code like this for another reason. I'll think it over later and see if such a modification will have any negative effects.
(20 14.5.30 note: at present, version 2.2.3 of quick-x has adopted this modification scheme).