A recent COCOS2DX project has undergone major changes. The data layer of the entire project has been moved from the C ++ layer to the LUA layer. Now the question is, how can I access the LUA data layer on the C ++ layer? As a newcomer to LUA, I am entangled. How many books does Nima have to chew on? If I told my boss that it would take me a week, I would probably be fired. But no way. The task is assigned. Let's get started.
The tutorial on accessing the LUA function in c ++ code can be said to cover every corner of the network. We will teach you how to use lua_pcall, lua_getglobal, lua_pushnumber, and so on. The basic requirements are as follows:
1. Access to common global functions (this is easy. If there are only one or two parameters and one or two return values, it can be handled)
2. Access to functions in the table (this Nima is pulled together with the table, and the package in LUA is the same as that in the table, making Nima more difficult)
3. The types of parameters and returned values can be INT, STRING, TABLE, or any number of parameters and returned values. (The number is not a problem. The PUSH in order is complete. How can we PUSH a table ???? This is a little difficult. It is estimated that you have to go back and have a good relationship with du Niang. What if this table is nested with a TABLE ??? Is it starting to hurt? There must be a certain requirement. To pass a two-dimensional or even three-dimensional array to the LUA function, do you dare say this requirement will not happen ?)
As a programmer, I need a class to manage all these tasks. So I designed a LuaAction class to simulate the entire function call process.
LuaAction has been uploaded, download page: http://download.csdn.net/detail/sunshine7858/6357979
The basic idea is as follows:
LuaAction lua; // create a LuaAction object lua. setModule (module); // set the package name. If the function does not have a package name, skip this line of lua. setFunction (func); // set the name of the function to be accessed, lua. addStringParam (argString); // Add the first string parameter. If not, skip lua. addIntParam (argInt); // Add the second int parameter. If not, skip lua. addTableParam (argTable); // Add the third table parameter. If not, skip ....... // Add more parameter lua.exe cuteFunction (resultnum); // core function, which is used to input the number of returned values, locate the function to be executed, press the parameter in, and read the return value. String retuslt0 = lua. getStringResult (0); // get 1st SRING return values int result1 = lua. getIntResult (1); // get 2nd INT return values table result2 = lua. getTableResult (2); // get the return value of 3rd tables
....
The most difficult part is how to recursively load the entire table. The detailed implementation details are complex and will not be described here. Basically, with this class, you can access all the public functions in LUA, just as you do at the LUA layer. Because LuaAction has implemented multi-level TABLE nesting, you can either input a multi-level TABLE or return a multi-level TABLE. This greatly facilitates the interaction between LUA and C ++.
However, before using LuaAction, you must call its initialization function once:
void LuaAction::initState(LuaState* state);
The rest is the same as the above process.
With this class, we can say that once and for all, I no longer have to worry about lua_gettop (), what lua_pushstring (), and so on. Go to hell, and you will never play again!
However, after a long time, the problem occurs again. We often find that some simple functions have only one parameter, no parameter, or just want to return a value. However, during the call, I still want to know all the external interfaces of LuaAction. It is probably just a simple string getName () function. I really want to write nearly five lines of code. It is really not cost-effective. I am tired of looking at it. Well, to improve code reusability, I wrap all these common functions. Creates a LuaAactionFactory class to access common functions. For example:
static void void_func_void(const char* module, const char* func); static void void_func_int(const char* module, const char* func, int arg1); static int int_func_void(const char* module, const char* func); static int int_func_int(const char* module, const char* func, int arg1); ........
For example, a function in Lua is as follows:
function getName(index) return tNames[index]end
LuaAction access code:
LuaAction lua; lua.setModule(module); lua.setFunction(func); lua.addIntParam(arg1); lua.executeFunction(1); return lua.getStringResult(0);
LuaActionFactory access code:
int ret = LuaActionFactory::int_func_int(NULL, "getName", 1)
Finally, we will give a simple demonstration of the transfer and acquisition of a 2-dimensional array:
The LUA function is as follows: function func (t) t [1] = 1 return tendLuaAction's return code: // create a table parameter LuaParamTable * table = new LuaParamTable () to be passed to the function; // set the following attributes: table-> setInt ("key1", 11 ); table-> setString ("key2", "value1"); table-> setInt (5, 22); table-> setString (6, "value2 "); // create a sub-Table LuaParamTable * subtable = new LuaParamTable (); subtable-> setInt ("key3", 5556); subtable-> setString ("key4", "value1 "); subtable-> setInt (3,444); subtable-> s EtString (4, "value3"); // mount the sub-table to the table in the master table> setTable ("table", subtable); LuaAction lua; // start LuaAction to call the lua function. setFunction ("func"); lua. addTableParam (table); // press the table into lua.exe cuteFunction (1); // execute the LuaParamTable tResult function; lua. getTableResultAndClear (& tResult, 0); // obtain the table object int a = tResult. getIntByIndex (1); // check the value assignment in LUA // compare the returned value with the previous value assignment. int value1 = tResult. getIntByKey ("key1"); string value2 = tResult. getStringByKey ("Key2"); int value3 = tResult. getIntByIndex (5); string value4 = tResult. getStringByIndex (6); LuaParamTable tSubResult; tResult. swapTableByKey ("table", & tSubResult); int value5 = tSubResult. getIntByKey ("key3"); string value6 = tSubResult. getStringByKey ("key4"); int value7 = tSubResult. getIntByIndex (3); string value8 = tSubResult. getStringByIndex (4); remember: when used as a table parameter, LuaParamTable is new because its lifecycle must be managed by LuaAction. When it is returned, LuaParamTable is directly created on the stack because it manages its own lifecycle.
I believe that with the above tools, most of the LUA functions can be accessed.