Step by step (LUA-c api Introduction)

Source: Internet
Author: User

Lua is an embedded scripting language, that is, Lua cannot be run independently.ProgramIn practice, there are two main application forms. The first form is that C/C ++ acts as the main program and calls LuaCodeIn this case, we can regard Lua as an extensible language. We call this application "application code ". The second form is that Lua has control, while C/C ++ code serves as the "library code" of Lua ". In both forms, the communication between the two languages is completed through the c api provided by Lua.

1. Basic Knowledge:
C API is a set of functions that allow C/C ++ code to interact with Lua. Including reading and writing Lua global variables, calling Lua functions, running a piece of Lua code, and registering C functions for Lua code calls. Here is a simple sample code:

 1 # Include <stdio. h>
2 # Include < String . H>
3 # Include <Lua. HPP>
4 # Include <lauxlib. h>
5 # Include <lualib. h>
6
7 Int Main ( Void )
8 {
9 Const Char * Buff = " Print (\ "Hello \") " ;
10 Int Error;
11 Lua_state * l = lual_newstate ();
12 Lual_openlibs (L );
13
14 Error = lual_loadbuffer (L, buff, strlen (buff ), " Line " ) | Lua_pcall (L, 0 , 0 , 0 );
15 Int S = lua_gettop (L );
16 If (Error ){
17 Fprintf (stderr, " % S " , Lua_tostring (L ,- 1 ));
18 Lua_pop (L, 1 );
19 }
20 Lua_close (L );
21 Return 0 ;
22 }

The following is a detailed explanation of the above Code:
1 ). the above code is based on my c ++ project, not the C project, so the header file contained is Lua. HPP. If it is a C Project, you can directly include Lua. h.
2) The Lua database does not define any global variables, but stores all states in the dynamic structure lua_state. All subsequent C APIs need this pointer as the first parameter.
3) The lual_openlibs function is used to open all standard libraries in Lua, such as the IO library and string library.
4). lual_loadbuffer compiles the Lua code in the buff. If there is no error, 0 is returned, and the compiled block is pushed into the virtual stack.
5) The lua_pcall function will pop up the program block from the stack and run the program block in protection mode. 0 is returned for successful execution. Otherwise, the error message is pushed to the stack.
6)-1 in the lua_tostring function indicates the index value at the top of the stack. The index value at the bottom of the stack is 1, and so on. This function will return the error message at the top of the stack, but it will not pop up from the stack.
7). lua_pop is a macro used to pop up a specified number of elements from the virtual stack. Here, 1 indicates that only the elements at the top of the stack are displayed.
8). lua_close is used to release the resources referenced by the Status pointer.

2. STACK:
During data exchange between Lua and C, there is a big difference between the two languages. For example, Lua is a dynamic type, C is a static type, and Lua is an automatic memory management, the C language is manual memory management. To solve these problems, Lua designers use the virtual stack as the medium for data interaction between the two. In a C/C ++ Program, to obtain the Lua value, you only need to call the c api function of Lua, and Lua will push the specified value into the stack. To pass a value to Lua, You need to first press the value into the stack, and then call Lua's c API, Lua will get the value and pop it up from the stack. To push different types of values into the stack and retrieve different types of values from the stack, Lua sets a specific function for each type.
1). Push element:
Lua corresponds to a c api function for each C type, for example:
Void lua_pushnil (lua_state * l );-- Nil value
Void lua_pushboolean (lua_state * l, int B );-- Boolean Value
Void lua_pushnumber (lua_state * l, lua_number N );-- Floating point number
Void lua_pushinteger (lua_state * l, lua_integer N );-- Integer
Void lua_pushlstring (lua_state * l, const char * s, size_t Len );-- Memory Data of the specified length
Void lua_pushstring (lua_state * l, const char * s );-- The length of a string ending with zero can be obtained by strlen.
For string data, Lua does not hold their pointers, but calls an API to generate an internal copy. Therefore, even if these string pointers are released or modified immediately after these functions are returned, and there will be no problems.
When loading data to the stack, you can call the following functions to determine whether there is sufficient stack space available. Generally, Lua reserves 20 slots, it is sufficient for common applications unless there are many parameters in the function.
Int lua_checkstack (lua_state * l, int extra)-- Expected to get the number of idle slots of extra. If it cannot be expanded and obtained, false is returned.

2). query element:
The API uses "Index" to reference the elements in the stack. The first one is 1, and the second one is 2. So on. We can also use a negative number as the index value, where-1 indicates the top element of the stack, and-2 indicates the bottom element of the stack, and so on.
Lua provides a set of specific functions to check the type of returned elements, such:
Int lua_isboolean (lua_state * l, int index );
Int lua_iscfunction (lua_state * l, int index );
Int lua_isfunction (lua_state * l, int index );
Int lua_isnil (lua_state * l, int index );
Int lua_islightuserdata (lua_state * l, int index );
Int lua_isnumber (lua_state * l, int index );
Int lua_isstring (lua_state * l, int index );
Int lua_istable (lua_state * l, int index );
Int lua_isuserdata (lua_state * l, int index );
If the preceding function is successful, 1 is returned; otherwise, 0 is returned. In particular, for lua_isnumber, You do not check whether the value is of the numeric type, but whether the value can be converted to the numeric type.
Lua also provides the lua_type function to obtain the element type. The function prototype is as follows:
Int lua_type (lua_state * l, int index );
The return value of this function is a group of constant values, which are: Lua_tnil, lua_tnumber, lua_tboolean, lua_tstring, lua_ttable, lua_tfunction, lua_tuserdata, lua_tthread, and lua_tlightuserdata . These constants are usually used in switch statements.
In addition to the above functions, Lua also provides a set of conversion functions, such:
Int lua_toboolean (lua_state * l, int index );
Lua_cfunction lua_tocfunction (lua_state * l, int index );
Lua_integer lua_tointeger (lua_state * l, int index );
Const char * lua_tolstring (lua_state * l, int index, size_t * Len );
Lua_number lua_tonumber (lua_state * l, int index );
Const void * lua_topointer (lua_state * l, int index );
Const char * lua_tostring (lua_state * l, int index );
Void * lua_touserdata (lua_state * l, int index );
-- String type returns the string length. The table Type returns the same result as the '#' operator. The userdata type returns the allocated memory block length.
Size_t lua_objlen (lua_state * l, int index );
If the call fails, lua_toboolean, lua_tonumber, lua_tointeger, and lua_objlen all return 0, while other functions return null. In many cases, 0 is not a very valid value for determining errors, but ansi c does not provide other values that can indicate errors. Therefore, in some cases, you need to use the lua_is * series functions to determine whether the type is correct. For the remaining functions, you can directly determine whether the return value is null.
The pointer to the internal string returned by the lua_tolstring function cannot be guaranteed to remain valid after the element to which the index points is popped up. The end of the string returned by this function has a tail value of 0.
A tool function is provided below to demonstrate some of the functions mentioned above, such:

 1   Static   Void Stackdump (lua_state * l)
2 {
3 Int Top = lua_gettop (L );
4 For ( Int I = 1 ; I <= top; ++ I ){
5 Int T = lua_type (L, I );
6 Switch (T ){
7 Case Lua_tstring:
8 Printf (" '% S' " , Lua_tostring (L, I ));
9 Break ;
10 Case Lua_tboolean:
11 Printf (lua_toboolean (L, I )? " True " : " False " );
12 Break ;
13 Case Lua_tnumber:
14 Printf ( " % G " , Lua_tonumber (L, I ));
15 Break ;
16 Default :
17 Printf (" % S " , Lua_typename (L, t ));
18 Break ;
19 }
20 Printf ( " " );
21 }
22 Printf ( " \ N " );
23 }

3) Other stack operation functions:
In addition to the data exchange functions provided above, Lua's c API also provides a set of common functions used to operate virtual stacks, such:
Int lua_gettop (lua_state * l );-- Returns the number of elements in the stack.
Void lua_settop (lua_state * l, int index );-- Set the top of the stack to the specified index value.
Void lua_pushvalue (lua_state * l, int index );-- Pushes the copy of the element of the specified index to the stack.
Void lua_remove (lua_state * l, int index );-- Delete the element on the specified index. The element above the index is automatically moved down.
Void lua_insert (lua_state * l, int index );-- Insert the top element of the stack to the position pointed to by the index value.
Void lua_replace (lua_state * l, int index );-- The top element of the stack is displayed, and the value is set to the specified index.
Lua also provides a macro to pop up a specified number of elements: # Define lua_pop (L, n) lua_settop (L,-(n)-1)
See the following sample code:

 1   Int Main ()
2 {
3 Lua_state * l = lual_newstate ();
4 Lua_pushboolean (L, 1 );
5 Lua_pushnumber (L, 10 );
6 Lua_pushnil (L );
7 Lua_pushstring (L, " Hello " );
8 Stackdump (L ); // True 10 nil 'hello'
9
10 Lua_pushvalue (L ,- 4 );
11 Stackdump (L ); // True 10 nil 'hello' true
12
13 Lua_replace (L, 3 );
14 Stackdump (L ); // True 10 true 'hello'
15
16 Lua_settop (L, 6 );
17 Stackdump (L ); // True 10 true 'hello' nil Nil
18
19 Lua_remove (L ,-3 );
20 Stackdump (L ); // True 10 true nil Nil
21
22 Lua_settop (L ,- 5 );
23 Stackdump (L ); // True
24
25 Lua_close (L );
26 Return 0 ;
27 }

3. c API error handling:
1 ). error handling when a C program calls Lua code:
generally, the application code runs in "unprotected" mode. Therefore, when Lua discovers errors such as "insufficient memory", it can only notify the C language program by calling the "emergency" function, and then end the application. You can use lua_atpanic to set your own "emergency" function. If you want the application code to not exit when a Lua error occurs, you can call lua_pcall function to run the Lua code in protected mode. In this case, when a memory error occurs, lua_pcall returns an error code and resets the interpreter to a consistent state. To protect the C code with Lua, you can use the lua_cpall function, which accepts a C function as a parameter, then call the C function.
2 ). lua calls the C program:
generally, when a C function called by Lua detects an error, it should call lua_error : This function cleans up all the resources to be cleared in Lua, redirects back to the lua_pcall that is initiated, and attaches an error message.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.