Getting started with cainiao, lua and c ++ call each other (including multiple DEMOS) and luademo
In the first two articles, we have introduced how to use vs2010 to compile lua5.1 source code to generate lua. lib and the vs project to use c ++ to call lua, which can ensure that the demo runs on. Here we will introduce in detail the mutual calls and principles between c ++ and lua.
C ++ and lua call directly transmits data through a stack structure. The index value at the top of the stack structure is-1, the index values at the bottom of the stack Are-1,-2 ...... the top index of the stack is 1. in the stack structure, you can store basic lua data such as functions, tables, strings, and shaping.
1. Create the test. lua file in the current cpp directory for interactive calling with c ++. The Code is as follows:
print("hello world from lua file")table1 = {}table1["dinner"] = "rice"table1["hahha"] = "ri123ce"gScreenW = 1280;function getIntegerSumFuncs(a ,b)<span style="white-space:pre"></span>return a + bendavg ,sum = average(10 ,20 ,30 ,40 ,50)
2. Familiarize yourself with the commonly used C language APIs of lua.
Int luaL_dofile (lua_State * L, const char * filename); // run the lua file. L is the currently created stack structure. 0 is returned, and the running file is normal. 1 is returned, indicating an exception.
Void lua_setglobal (lua_State * L, const char * name); // a value is displayed from the stack and set it to the global variable name.
Void lua_getglobal (lua_State * L, const char * name); // press the value in the global variable name into the stack. The top value of the stack is-1.
Const char * lua_tostring (lua_State * L, int index); // the index value of stack L is the index value and converted into a C string (similar to lua_tointeger)
Void lua_settop (lua_State * L, int index); // The parameter allows passing in any acceptable index and 0. It sets the top of the stack as the index. If the new stack is larger than the original one, the new elements in the excess part will be filled with nil. If the index is 0, all elements on the stack are removed.
Int lua_gettop (lua_State * L); // returns the number of elements on the stack (0 indicates that the stack is empty)
Int lua_next (lua_State * L, int index); a key (key) pops up from the stack, and then the key-value (key value) in the table specified by the index) press the pair into the stack (specify the next pair after the key ). If there are no more elements in the table, lua_next returns 0 (nothing is pushed into the stack ).
Void lua_pushinteger (lua_State * L, lua_Integer n); // use n as a digital pressure stack.
Void lua_close (lua_State * L); // destroy all objects in the specified Lua state machine
If you need to query other functions, we recommend that you go to the Lua 5.1 reference manual, which is detailed and accurate.
3. c ++ obtains the global string in lua.
// Obtain lua global stringconst char * getLuaGlobalString (char * fileName, char * varName) {lua_State * L = lua_open (); luaL_openlibs (L); // load and run test. lua file int isOpen = luaL_dofile (L, fileName); if (isOpen = 0) {printf ("error loading lua ");} // set the index on the top of the stack to this index. If the index is 0, remove all the elements lua_settop (L, 0) on the stack ); // press the value in global variable allGlobalChar into the stack. Char * allGlobalChar = varName; lua_getglobal (L, allGlobalChar); int stateCode = lua_isstring (L, 1); if (stateCode! = 1) {printf ("open lua error code: % d", stateCode); return NULL;} const char * s = lua_tostring (L, 1 ); printf ("get global screenW is: % s \ n", s); lua_pop (L, 1); lua_close (L); return s ;}
Call code:
getLuaGlobalString("test.lua" ,"gScreenW");
4. c ++ obtain the value in lua table
Const char * getLuaVarOfTable (const char * fileName, const char * tableName, const char * keyName) {lua_State * L = lua_open (); luaL_openlibs (L ); int isOpen = luaL_dofile (L, fileName); if (isOpen! = 0) {printf ("error open lua file"); return NULL;} lua_settop (L, 0); // clear the stack lua_getglobal (L, tableName ); int stateCode = lua_istable (L,-1); // get the top of the stack if (stateCode! = 1) {printf ("get table failed code: % d", stateCode); return NULL;} lua_pushstring (L, keyName); lua_gettable (L,-2 ); // take the first element of the stack, const char * valueStr = lua_tostring (L,-1 ); // obtain the top of the stack printf ("get lua table key-value % s-% s", keyName, valueStr); lua_pop (L,-1); return valueStr ;}
Call code:
getLuaVarOfTable("test.lua" ,"table1" ,"dinner");
V. c ++ obtain the table in lua
<Pre name = "code" class = "java"> string getLuaVarTable (const char * fileName, const char * tableName, char * result) {lua_State * L = lua_open (); luaL_openlibs (L); int isOpen = luaL_dofile (L, fileName); if (isOpen! = 0) {printf ("error open lua file"); return NULL;} lua_getglobal (L, tableName); int size = lua_gettop (L); lua_pushnil (L ); int index = 0; while (lua_next (L, size) {const char * key = lua_tostring (L,-2 ); // take the top and next element of the stack const char * value = lua_tostring (L,-1); // take the top of the stack // use memcpy, index record address cursor memcpy (& result [index], key, strlen (key); index + = strlen (key); // the string is obtained because sizeof, "/0" occupies one byte, so we should subtract 1 memcpy (& result [index], "-", sizeof ("-")-1 ); index + = 1; memcpy (& result [index], value, strlen (value); index + = strlen (value); lua_pop (L, 1 );} result [index] = 0; cout <"result is" <result <endl; // free (result); // printf ("--- % s", result. c_str); lua_pop (L, 1); return result ;}
Call code:
char* reslut = (char*)malloc(100 * sizeof(char));getLuaVarTable("test.lua" ,"table1" ,reslut);free(reslut);
6. cpp calls functions in lua
// Follow the following protocol to call a function: first, the function to be called should be pushed into the stack; // then, the parameters to be passed to this function should be pushed to the stack in a forward order; this means that the first parameter first presses the stack. // Finally, call lua_call. nargs is the number of parameters you press into the stack. // After the function is called, all parameters and functions will go out of the stack. The Return Value of the function is pushed into the stack. // The number of returned values will be adjusted to nresults, unless nresults is set to LUA_MULTRET. // In this case, all returned values are pushed into the stack. Lua ensures that the returned values are stored in the stack space. // The function return value is pushed to the stack in positive order (the first return value is pushed to the stack first). Therefore, after the call is completed, the last return value is placed at the top of the stack. Const char * callLuaFunc (const char * fileName, const char * functionName) {lua_State * L = lua_open (); luaL_openlibs (L); int isOpen = luaL_dofile (L, fileName ); if (isOpen! = 0) {printf ("error open lua file % s", fileName); return NULL;} lua_getglobal (L, functionName); // If the table and function have duplicate names, what will happen to lua_pushinteger (L, 12); lua_pushinteger (L, 3); // The first parameter: number of functions second parameter: number of returned values of functions lua_call (L, 2, 1); int result = lua_tointeger (L,-1); printf ("call lua func result: % d", result); return NULL ;}
Call code:
callLuaFunc("test.lua" ,"getIntegerSumFuncs");
VII. lua calls the cpp function to calculate the average value
// The int average (lua_State * L) {int n = lua_gettop (L); double sum = 0; int I; for (I = 1; I <= n; I ++) {if (! Lua_isnumber (L, I) {lua_pushstring (L, "incorrect argument to avg"); lua_error (L);} sum + = lua_tonumber (L, I );} lua_pushnumber (L, sum/n); lua_pushnumber (L, sum); // The number of elements must be returned. If 0 is returned, return 2 is not found ;} // lua calls cpp to calculate the average value, and calls the int averageMain () {lua_State * L = lua_open (); luaL_openlibs (L); // registers the lua function, actually, the average is pushed to the stack structure, and the set average function is the global function lua_register (L, "average", average); // run the script luaL_dofile (L, "test. lua "); // press the value in the global variable avg into the stack lua_getglobal (L," avg "); // The stack top is-1, the bottom stack is 1 cout <"cpp show: avg is" <lua_tointeger (L,-1) <endl; // an element pops up from the stack // lua_pop (L, 1); // press the value in sum of the global variable into the stack lua_getglobal (L, "sum "); cout <"cpp show: sum is" <lua_tointeger (L,-1) <endl; // clear the stack structure lua_close (L); return 0 ;}
Code call:
averageMain();
The above is a common demo for c ++ and lua calls.
The attached project example: http://download.csdn.net/detail/wangbin_jxust/7809743
If you need to run this project, you need to use vs2010 to compile lua5.1 source code to generate lua. lib configuration again, and then run it again.