Lua Tutorial (19): C Call Lua_lua

Source: Internet
Author: User
Tags lua

1. Foundation:

One of the most important uses of LUA is as a configuration language. Now let's start with a simple example.

Copy Code code as follows:

--Here is the configuration information for the window size defined with the LUA code
width = 200
Height = 300

Here is the C + + code to read configuration information:

Copy Code code as follows:

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

Void Load (lua_state* L, const char* fname, int* W, int* h) {
    if (lual_loadfile (l,fname) | | lua_p Call (l,0,0,0)} {
        printf ("Error Msg is%s.\n", lua_tostring (l,-1));
        return;
   }
    Lua_getglobal (L, "width");
    Lua_getglobal (L, "height");
    if (!lua_isnumber (l,-2)) {
        printf (' width ' Should be a number\n ");
        return;
   }
    if (!lua_isnumber (l,-1)) {
        printf (' Height ' Should be a number\n ");
        return;
   }
    *w = Lua_tointeger (l,-2);
    *h = Lua_tointeger (l,-1);
}


int main ()
{
lua_state* L = Lual_newstate ();
int w,h;
Load (L, "D:/test.lua", &w,&h);
printf ("width =%d, height =%d\n", w,h);
Lua_close (L);
return 0;
}

The following is an explanation for the new function:

The Lua_getglobal is a macro, and its prototype is: #define LUA_GETGLOBAL (l,s) Lua_getfield (L, Lua_globalsindex, (s)).

Every time this macro is invoked, the corresponding global variable value in the LUA code is pushed into the stack, and the value of the global variable "width" is pressed into the stack on the first call, and then the value of "height" is also pressed into the stack when called again.

2. Table Operation:

We can manipulate the table data in Lua in the C language code, which is a very, very handy and useful feature. This not only makes the structure of the LUA code clearer, but also defines the equivalent structure in the C language code, which can greatly improve the readability of the code. See the following code:

Copy Code code as follows:

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

void load (lua_state* L) {

if (lual_loadstring (L, "background = {r = 0.30, G = 0.10, b = 0}")
|| Lua_pcall (l,0,0,0)) {
printf ("Error Msg is%s.\n", lua_tostring (l,-1));
Return
}
Lua_getglobal (L, "background");
if (!lua_istable (l,-1)) {
printf ("' Background ' is not a table.\n");
Return
}
Lua_getfield (l,-1, "R");
if (!lua_isnumber (l,-1)) {
printf ("Invalid component in Background color.\n");
Return
}
int r = (int) (Lua_tonumber (l,-1) * 255);
Lua_pop (l,1);
Lua_getfield (L,-1, "G");
if (!lua_isnumber (l,-1)) {
printf ("Invalid component in Background color.\n");
Return
}
int g = (int) (Lua_tonumber (l,-1) * 255);
Lua_pop (l,1);

Lua_pushnumber (l,0.4);
Lua_setfield (l,-2, "B");

Lua_getfield (l,-1, "B");
if (!lua_isnumber (l,-1)) {
printf ("Invalid component in Background color.\n");
Return
}
int b = (int) (Lua_tonumber (l,-1) * 255);
printf ("R =%d, G =%d, B =%d\n", r,g,b);
Lua_pop (l,1);
Lua_pop (l,1);
Return
}

int main ()
{
lua_state* L = Lual_newstate ();
Load (L);
Lua_close (L);
return 0;
}

void Lua_getfield (lua_state *l, int idx, const char *k); The second parameter is the index value of the table variable on the stack, and the last parameter is the key value of the table, which pushes the field value into the stack after the function is successfully executed.

void Lua_setfield (lua_state *l, int idx, const char *k); The second parameter is the index value of the table variable on the stack, the last parameter is the key name of the table, and the field value is pushed into the stack by the previous command Lua_pushnumber (l,0.4), which pops up the field value just pressed in after the execution succeeds.

The following code example constructs a Table object in the C language code, initializes the field value of the table, and finally assigns the Table object to a global variable in Lua.

Copy Code code as follows:

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

void load (lua_state* L)
{
Lua_newtable (L);
Lua_pushnumber (l,0.3);
Lua_setfield (L,-2, "R");

Lua_pushnumber (l,0.1);
Lua_setfield (L,-2, "G");

Lua_pushnumber (l,0.4);
Lua_setfield (l,-2, "B");
Lua_setglobal (L, "background");

Lua_getglobal (L, "background");
if (!lua_istable (l,-1)) {
printf ("' Background ' is not a table.\n");
Return
}
Lua_getfield (l,-1, "R");
if (!lua_isnumber (l,-1)) {
printf ("Invalid component in Background color.\n");
Return
}
int r = (int) (Lua_tonumber (l,-1) * 255);
Lua_pop (l,1);
Lua_getfield (L,-1, "G");
if (!lua_isnumber (l,-1)) {
printf ("Invalid component in Background color.\n");
Return
}
int g = (int) (Lua_tonumber (l,-1) * 255);
Lua_pop (l,1);

Lua_getfield (l,-1, "B");
if (!lua_isnumber (l,-1)) {
printf ("Invalid component in Background color.\n");
Return
}
int b = (int) (Lua_tonumber (l,-1) * 255);
printf ("R =%d, G =%d, B =%d\n", r,g,b);
Lua_pop (l,1);
Lua_pop (l,1);
Return
}

int main ()
{
lua_state* L = Lual_newstate ();
Load (L);
Lua_close (L);
return 0;
}

The code above will output the same result as the previous code.

Lua_newtable is a macro whose prototype is: #define LUA_NEWTABLE (L) lua_createtable (l, 0, 0). When the macro is invoked, LUA generates a new Table object and presses it onto the stack.

Lua_setglobal is a macro that is a prototype: #define LUA_SETGLOBAL (l,s) Lua_setfield (L,lua_globalsindex, (s)). When the macro is invoked, Lua assigns the value of the current top stack to the global variable name specified by the second parameter. After the macro succeeds, it pops the value just assigned from the top of the stack.

3. Call the LUA function:

The API for calling a function is also simple. The call function is first pushed into the stack, then pressed into the function's arguments, and then the actual call is made using Lua_pcall, and finally the call result is ejected from the stack. See the following code:

Copy Code code as follows:

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

Const char* Lua_function_code = "function Add (x,y) return x + y end";

void Call_function (lua_state* L)
{
Lual_dostring equivalent to lual_loadstring () | | Lua_pcall ()
Note: You must execute the LUA script before you can call the LUA function, otherwise you will get an error when you actually call the LUA function later.
The error message is: "Attempt to call a nil value."
if (lual_dostring (L,lua_function_code)) {
printf ("Failed to run Lua code.\n");
Return
}
Double x = 1.0, y = 2.3;
Lua_getglobal (L, "add");
Lua_pushnumber (L,X);
Lua_pushnumber (L,y);
The second argument below indicates that there are two parameters for the LUA function with calls.
The third parameter means that even if there are multiple return values in the called function, only one is pushed into the stack after execution.
After the Lua_pcall call, the function parameters and function names in the virtual stack are ejected.
if (Lua_pcall (l,2,1,0)) {
printf ("Error is%s.\n", lua_tostring (l,-1));
Return
}
The result has been pushed into the stack.
if (!lua_isnumber (l,-1)) {
printf ("function ' add ' must return a number.\n");
Return
}
DOUBLE ret = Lua_tonumber (l,-1);
Lua_pop (l,-1); The return value pops up.
printf ("The result of called function is%f.\n", ret);
}

int main ()
{
lua_state* L = Lual_newstate ();
Call_function (L);
Lua_close (L);
return 0;
}

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.