Lua Tutorial (17): Introduction to the C API _lua

Source: Internet
Author: User
Tags error code function prototype lua true true

Lua is an embedded scripting language, that is, LUA is not a stand-alone program, and in practice, there are two main forms of application. The first is that C/s + + as the main program invokes the LUA code, which at this point can be viewed as "extensible language", which we call "application code". The second form is that Lua has control, while the C + + code acts as a Lua "library code." In both of these forms, communication between the two languages is accomplished through the C API provided by LUA.

1. Basic knowledge:

The C API is a set of functions that can interact with the Lua-C + + code. These include reading and writing LUA global variables, calling LUA functions, running a section of LUA code, and registering C functions for LUA code invocation. Here's a simple example code:

Copy Code code as follows:

#include <stdio.h>
#include <string.h>
#include <lua.hpp>
#include <lauxlib.h>
#include <lualib.h>

int main (void)
{
Const char* buff = "Print (\" hello\ ")";
int error;
lua_state* L = Lual_newstate ();
Lual_openlibs (L);

Error = Lual_loadbuffer (L,buff,strlen (Buff), "line") | | Lua_pcall (l,0,0,0);
int s = lua_gettop (L);
if (Error) {
fprintf (stderr, "%s", Lua_tostring (l,-1));
Lua_pop (l,1);
}
Lua_close (L);
return 0;
}


The following is a specific explanation for the above code:

1. The code above is based on my C + + project, not C engineering, so the header file included is LUA.HPP, if it is C engineering, can directly include lua.h.
2. The LUA library does not define any global variables, but instead saves all states in the dynamic structure lua_state, which all subsequent C APIs require as the first parameter.
3. The Lual_openlibs function is used to open all the standard libraries in Lua, such as IO libraries, string libraries, and so on.
4. Lual_loadbuffer compiles the LUA code in buff, returns 0 if there are no errors, and presses the compiled block into the virtual stack.
5. The Lua_pcall function pops the program block out of the stack and runs the block in protected mode. Execution successfully returns 0, otherwise the error message is pushed onto the stack.
6. The lua_tostring function, 1, represents the index value at the top of the stack, the index value at the bottom of the stack is 1, and so on. The function will return the error message at the top of the stack, but will not eject it from the stack.
7. Lua_pop is a macro that pops a specified number of elements from the virtual stack, where 1 represents only the elements that pop up the top of the stack.
8). Lua_close is used to free the resources referenced by the status pointer.

2. Stack:

In the case of data exchange between LUA and C, there are significant differences between the two languages, such as Lua being dynamic, C is a static type, LUA is automatic memory management, and the C language is manual memory management. To address these problems, the LUA designers used the virtual stack as a medium for data interaction between the two. In C + + programs, if you want to get the value of LUA, just call the LUA C API function, and LUA pushes the specified value into the stack. To pass a value to LUA, you need to push the value onto the stack, and then call Lua's C Api,lua to get the value and eject it from the stack. To allow different types of values to be pushed onto the stack and to fetch different types of values from the stack, LUA sets a specific function for each type.

1). Press into the element:

LUA has a C API function that corresponds to each C type, such as:

Copy Code code as follows:

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 numbers
void Lua_pushinteger (lua_state* L, Lua_integer N); --Integral type
void Lua_pushlstring (lua_state* L, const char* s, size_t len); --Specified length of memory data
void Lua_pushstring (lua_state* L, const char* s); --a string ending in 0 with a length that can be drawn from strlen.

For string data, LUA does not hold their pointers, but instead calls to generate an internal copy when the API is generated, so even if they are released or modified immediately after these functions return, there is no problem.
When you press the data into the stack, you can call the following function to determine whether there is enough stack space available, in general, Lua will reserve 20 slots, for ordinary applications is enough, unless you encounter a number of parameters of the function.
int Lua_checkstack (lua_state* L, int extra)--expects to get a extra number of free slots, and returns False if it cannot be extended and obtained.

2). Query elements:

The API uses "index" to refer to the elements in the stack, the first to push the stack to 1, the second to 2, and so on. We can also use negative numbers as index values, where 1 is the top element of the stack, and 2 is the element below the top of the stack, and so on.

LUA provides a set of specific functions for checking the type of return elements, such as:

Copy Code code as follows:

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);

The above function returns 1 successfully, otherwise it returns 0. It should be noted that for Lua_isnumber, the value is not checked for numeric types, but rather whether the value can be converted to a numeric type.
LUA also provides a function lua_type to get the type of the element, which is the following function prototype:
Copy Code code as follows:

int Lua_type (lua_state *l, int index);

The return value of the function is a set of constant values, respectively: Lua_tnil, Lua_tnumber, Lua_tboolean, lua_tstring, lua_ttable, Lua_tfunction, Lua_tuserdata, LUA_ TThread and Lua_tlightuserdata. These constants are commonly used in switch statements.
In addition to the above functions, LUA provides a set of transformation functions, such as:
Copy Code code as follows:

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);
The--string type returns the string length, the table type returns the result of the operator ' # ' equivalent, and the UserData type returns the allocated memory block length.
size_t Lua_objlen (lua_state *l, int index);

For the above function, if the call fails, Lua_toboolean, Lua_tonumber, Lua_tointeger, and Lua_objlen return 0, while the other functions return null. In many cases 0 is not a very effective value for judging errors, but ANSI C does not provide other values that can represent errors. So for these functions, in some cases it is necessary to use the Lua_is* series function to determine whether the type is correct, and for the remainder of the function, you can directly determine whether the return value is null or not.
A pointer to an internal string returned by the Lua_tolstring function cannot be guaranteed to remain valid after the element to which the index points is ejected. The function returns a trailing 0 at the end of the string.
The following is a tool function that can be used to demonstrate some of the functions mentioned above, such as:
Copy Code code as follows:

static void Stackdump (lua_state* L)
{
int top = lua_gettop (L);
for (int i = 1; I <= top; ++i) {
int t = lua_type (l,i);
Switch (t) {
Case lua_tstring:
printf ("'%s '", Lua_tostring (L,i));
Break
Case Lua_tboolean:
printf (Lua_toboolean (l,i)? "True": "false");
Break
Case Lua_tnumber:
printf ("%g", Lua_tonumber (L,i));
Break
Default
printf ("%s", Lua_typename (l,t));
Break
}
printf ("");
}
printf ("\ n");
}

3). Other stack operation functions:

In addition to the data interchange functions given above, the LUA C API provides a set of common functions for manipulating virtual stacks, such as:

Copy Code code as follows:

int Lua_gettop (lua_state* L); --Returns the number of elements in the stack.
void Lua_settop (lua_state* L, int index); --Sets the top of the stack to the specified index value.
void Lua_pushvalue (lua_state* L, int index); --Pushes the element copy of the specified index into the stack.
void Lua_remove (lua_state* L, int index); --Deletes the element on the specified index, and the element above it is automatically moved down.
void Lua_insert (lua_state* L, int index); --Inserts the top element of the stack at the point where the index value points.
void Lua_replace (lua_state* L, int index); --pops up the top element of the stack and sets the value to the specified index.

LUA also provides a macro that pops up a specified number of elements:
Copy Code code as follows:
#define LUA_POP (L,n) lua_settop (L,-(n)-1)

See the following sample code:
Copy code code as follows:

int main ()
{
    lua_state* L = Lual_newstate ();
    Lua_pushboolean (l,1);
    Lua_pushnumber (l,10);
    Lua_pushnil (L);
    lua_pushstring (L, "Hello");
    stackdump (L);//true nil ' hello '

    lua_pushvalue (l,-4);
&nbs p;   Stackdump (L); True nil ' hello '

    lua_replace (l,3);
    stackdump (L);//true-TR UE ' Hello '

    lua_settop (l,6);
    stackdump (L);//true true ' hello ' nil ni L

    lua_remove (l,-3);
    stackdump (l);//true true nil nil

&NBSP ;   lua_settop (l,-5);
    stackdump (L);//true

    lua_close (L);
    return 0;
}

3. Error handling in the C API:

1. C Program calls the LUA code error handling:

In general, the application code is run in "unprotected" mode. Therefore, when Lua discovers an "out-of-memory" error, it can only notify the C language program by calling the "emergency" function, and then at the end of the application. Users can set their own "emergency" functions by Lua_atpanic. If you want your application code to not quit when a LUA error occurs, you can run the LUA code in protected mode by calling the Lua_pcall function. When a memory error occurs, Lua_pcall returns an error code and resets the explanation to a consistent state. If you want to protect the C code with LUA, you can use the Lua_cpall function, which takes a C function as an argument, and then calls the C function.

2. Lua invokes the C program:

Typically, when an error is detected by a C function called by LUA, it should call Lua_error, which cleans up all the resources in Lua that need to be cleaned up, then jumps back to the lua_pcall that initiated the execution 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.