AboutLua StackIntroduction and examples are the content of this article, mainlyStackInLuaFor details about how to use it, see this article. Load in c ++LuaCode
- # Include <> // The required header file
- Extern "C"
- {
- # Include "include \ lua. h"
- # Include "include \ lualib. h"
- # Include "include \ lauxlib. h"
- # Pragma comment (lib, "lua. lib ")
- };
-
- Int main (void)
- {
- Char buff [256]; // Stack
- Int error; // error code
- Lua_State * L = lua_open (); // lua pointer
- LuaL_openlibs (L); // load all lua Databases
- // Add the required code here...
- Lua_close (L); // close lua
- Return 0;
- }
The method for loading data into Programming in lua is to load five databases, namely base, table, io, string, and math, but lua5.1.3 + vs is in use. net2003) When I/O Library is loaded, an error occurs, and the program cannot be executed, but no error is prompted.
I checked it online and some people encountered illegal memory reference here.) His solution was to change it to the method in the code above: load all the databases directly.
Here is an explanation: "regarding the luaopen_io call failure, I asked in maillist of Lua, some people say that some functions in the I/O Library depend on the specific environment established by Lua. Therefore, you must use lua_call to call them. Alternatively, you can directly use luaL_openlibs to introduce all the standard libraries. I looked at the help documentation and the Lua source code. It seems like this is the case !"
Check the official document http://www.lua.org/manual/5.1/manual.html) has a paragraph:
- To have access to these libraries, the C host program should call the luaL_openlibs function,
- which opens all standard libraries. Alternatively, it can open them individually by calling luaopen_base (for the basic library),
- luaopen_package (for the package library), luaopen_string (for the string library),
- luaopen_table (for the table library), luaopen_math (for the mathematical library),
- luaopen_io (for the I/O library), luaopen_os (for the Operating System library),
- and luaopen_debug (for the debug library).
- These functions are declared in lualib.h and should not be called directly: you must call them like any other Lua C function, e.g.,
- by using lua_call. "
The last sentence means: "These functions are defined in lualib. h and cannot be called directly: You must call other C functions, such as lua_call ."
The usage of lua_call is as follows:
Lua_call
Prototype: void lua_call (lua_State * L, int nargs, int nresults );
Calla function.
Function: Call a method.
To call a function, follow the following rules: first, the function to be called is put into the stack; then, function parameters are put into the stack in order, that is, the first parameter is first put into the stack. Finally, call lua_call; nargs is the number of parameters in the stack. When a function is called, all parameters and function values are displayed. After the function is returned, the function result is pushed to the stack. The number of results depends on the last parameter of nresultslua_call ). Unless the nresults value is LUA_MULTRET. In this way, all function results are written into the stack. These return values in the stack space are managed by Lua. Function results are first added to the stack in sequence), so the last parameter is placed at the top of the stack after the call is complete.
- Any error inside the called function is propagated upwards (with a longjmp).
Errors generated in function calls are passed up using the longjmp method ).
- The following example shows how the host program may do the equivalent to this Lua code:
The following example shows how to make the Host Program Implement the following lua code:
- a = f("how", t.x, 14)
- it is in C:
This is in C:
- lua_getfield(L, LUA_GLOBALSINDEX, "f"); /* function to be called */
- lua_pushstring(L, "how"); /* 1st argument */
- lua_getfield(L, LUA_GLOBALSINDEX, "t"); /* table to be indexed */
- lua_getfield(L, -1, "x"); /* push result of t.x (2nd arg) */
- lua_remove(L, -2); /* remove 't' from the stack */
- lua_pushinteger(L, 14); /* 3rd argument */
- lua_call(L, 3, 1); /* call 'f' with 3 arguments and 1 result */
- lua_setfield(L, LUA_GLOBALSINDEX, "a"); /* set global 'a' */
If you do not understand it, I do not understand it.) load the lua database directly in the method written in the top code.
I have been learning LUA for some time. I personally think it is very important to understand the stack in LUA. Well, it is really small to write a small article)
If you read the LUA document, you should be clear that LUA uses the so-called stack in LUA when interacting with C. So what is the stack after I call the lua_open function? Empty luaopen_base will be added to the stack ). As for how to operate the data on the stack, I think the official document has already been very clear, but at first I was confused about the stack sequence, so let's talk about it. Now let's assume that I have the following code:
- lua_State* L = lua_open();
- lua_pushnumber( L, 211 );
- lua_pushnumber( L, 2222 );
- lua_newtable( L );
- lua_close( L );
After executing lua_newtable, the stack has three elements, which are roughly like this:
- 211
- 222
- table
Now 211 is the first element and index is 1, but LUA can also be expressed as a negative number. What is it now?
- index -index value
- 1 -3 211
- 2 -2 222
- 3 -1 table
Well, it's easy. Let's see how to set a TABLE value? What is the difference between lua_settable and lua_rawset in this document?) Their parameter meanings and preparations are the same.-1 is the value and-2 is the key value.
- lua_settable( lua_state*, int )
The first parameter is the script environment to be operated, and the second parameter is the position of the table to be operated on the stack.
The general statement may be as follows:
- // Code
- Lua_getglobal (L, "myTable"); // obtain the table for which you want to set the value
- Lua_pushstring (L, "hp"); // the position of "hp" on the stack is-1.
- Lua_pushnumber (L, 211); // the value of "hp" on the stack is-2, while that of 211 is-1.
- Lua_settable (L,-3); // The value is correctly set to the myTable of the global variable table.
What if I want to set the hp value to the global table? Generally, you can call the lua_setglobal macro
- lua_pushnumber( L, 211 );
- lua_setglobal( L, "hp" );
This is simple, but let's take a look at the macro lua_setglobal.
- #define lua_setglobal(L,s) \
-
- (lua_pushstring(L, s), lua_insert(L, -2), lua_settable(L, LUA_GLOBALSINDEX))
In this case, the above Code is replaced
- Lua_pushnumber (L, 211 );
- Lua_pushstring (L, "hp ");
- Lua_insert (L,-2); // This step may seem strange. In fact, we put the value of-1 to the position indicated by the second parameter of lua_insert, then the parameters following this position are moved up.
- // In fact, the final result is-1 and-2, but not logically
- Lua_settable (L, LUA_GLOBALSINDEX); // Why not use lua_rawset? I think there is a reason ^ @ ^
By combining the above Code with code A, we can see that the index value is different when lua_settable is used. If we find that the index is LUA_GLOBALSINDEX, we can retrieve the global table and have A LUA_REGISTERINDEX, (Similar). Otherwise, an element is retrieved from the stack. Of course, if not a table is retrieved from the stack location, it will fail. Therefore, code A specifies that-3 is the myTable table just retrieved from the global table. Here we assume it is A table.) The above code snippet is the global table. Therefore, the index of lua_settable can be any value, as long as it points to a table
In fact, the interfaces between lua and c are mainly on Stack operations, basically, when you write a program that combines lua and C, the most important thing you need to do is to understand what elements and their locations are on your current stack. I usually draw their positions on the paper. If you are familiar with it, you can quickly see the stack changes for the lua calls that are associated with each other. For example
- lua_gettable/lua_rawget
-
- lua_pushstring( L, "hp" );
- lua_gettable( L, LUA_GLOBALSINDEX );
Let's just look at the first sentence. The top of the stack is a string, but the two sentences are put together. The top of the stack is the actual value named hp on a global table.
- lua_pushstring( L, "hp" );
- lua_pushnumber( L, 211 );
- lua_settable( L, LUA_GLOBALSINDEX );
No matter whether the second sentence pushnumber, pushvalue, pushstring or something, the execution of these three sentences will not change for the stack, because lua_settable/lua_rawset will remove-1 and-2.
In short, for Stack changes, when reading a function document, first check its parameters and the elements at the positions on the stack and correctly set the values on the stack, it is clear that he will take the elements at the positions on the stack as the use of this lua api call and place the correct values on the stack, finally, after the function is completed, the elements at those locations will be cleared/removed. I think it should be okay.
- lua_gettable
- lua_getglobal(L, "mytable") <== push mytable
- lua_pushnumber(L, 1) <== push key 1
- lua_gettable(L, -2) <== pop key 1, push mytable[1]
-
- lua_settable
- lua_getglobal(L, "mytable") <== push mytable
- lua_pushnumber(L, 1) <== push key 1
- lua_pushstring(L, "abc") <== push value "abc"
- lua_settable(L, -3) <== mytable[1] = "abc", pop key & value
Lua_rawget:
The usage is the same as that of lua_gettable, but it is faster (because the meta-method _ index is not required when the key does not exist)
Lua_rawset:
The usage is the same as lua_settable, but it is faster (because when the key does not exist, you do not need to access the metadatabase _ newindex)
Lua_rawgeti must be a numerical key.
- Lua_getglobal (L, "mytable") <= push mytable
- Lua_rawgeti (L,-1, 1) <= push mytable [1], which is called in the following two rows
- -- Lua_pushnumber (L, 1) <= push key 1
- -- Lua_rawget (L,-2) <= pop key 1, push mytable [1]
Lua_rawseti must be a numerical key.
- lua_getglobal(L, "mytable") <== push mytable
- lua_pushstring(L, "abc") <== push value "abc"
- lua_rawseti(L, -2, 1) <== mytable[1] = "abc", pop value "abc"
Lua_getfield must beStringKey
- Lua_getglobal (L, "mytable") <= push mytable
- Lua_getfield (L,-1, "x") <= push mytable ["x"], which is called by the following two lines
- -- Lua_pushstring (L, "x") <= push key "x"
- -- Lua_gettable (L,-2) <= pop key "x", push mytable ["x"]
Lua_ Setfield must beStringKey
- lua_getglobal(L, "mytable") <== push mytable
- lua_pushstring(L, "abc") <== push value "abc"
- lua_setfield(L, -2, "x") <== mytable["x"] = "abc", pop value "abc"
Details: DetailsLua StackThe introduction and instance content have been introduced. I hope this article will help you!