The Lua tutorial (v): C + + operations Lua Array and string example _lua

Source: Internet
Author: User
Tags lua sprintf

This article will explain how to manipulate LUA arrays and string types in C + +, as well as how to store the LUA State (registry and Upvalue) in C + + functions, and Registry is useful when using C + + custom types. You can easily specify metatable for UserData.

C + + operations Lua array

Lua Array Overview

In Lua, an array is nothing more than a table with key integers. For example, a table is an array = {, "Hello", "World"}, which is a list that can be accessed using the following code:

Copy Code code as follows:

Print (array[1])--This will output the first element of array 12.
Print (array[3])--This will output the third element of the array world

One thing to note is that the subscripts of the LUA array start at 1. If you use the following statement, you will output the nil value:

Copy Code code as follows:

Print (array[0])--Output nil
Print (array["1"])--the difference between output nil (think and array[1): One is integer as key, one is string as key.

General Table Operation method

In tutorial 1, we described how to pass table to Lua, and how to access the table's data in Tutorial 3. Because the array is also a table, we can read the array in the same way.

Reading arrays

Assuming our LUA table is array = {"Hello", 1, "World", 23.2}, we can use the following functions to access it:

Copy Code code as follows:

void Readluaarray (Lua_state *l)
{
Lua_settop (l,0); This ensures that our array is placed at the top of the stack on the current stack.
Lua_getglobal (L, "array");
If the front does not call Lua_settop (l,0), then we have to use Lual_len (l,-1)
int n = Lual_len (L, 1); Lual_len can get the number of elements in a table
for (int i = 1; I <= n; ++i) {
Lua_pushnumber (L, i); Into the stack inside I
Lua_gettable (L,-2); Read the location of the table[i],table at-2.
Lua_rawget (L,-2); Lua_gettable can also be replaced with Lua_rawget.
Cout<<lua_tostring (L,-1) <<endl;
Lua_pop (L, 1);
}
}

The result of the final output is:

Copy Code code as follows:

"Hello", 1, "World", 23.2

Modifying an array

Now if we want to modify this array, we'll change the elements of each one into "hehe[i" (i = 1-n), and we'll see what we can do.

Copy Code code as follows:

int Writeluaarray (lua_state *l)
{
Lua_settop (L, 0);
Lua_getglobal (L, "array");
Make sure that the first function is a table
Lual_checktype (L, 1, lua_ttable);
int n = lual_len (l,1);
for (int i = 1; I <= n; ++i) {
Lua_pushnumber (L, i);
Char buf[256];
sprintf (buf, "hehe%d", I);
Lua_pushstring (L, buf);
Lua_settable (L,-3);
Lua_rawset (L,-3);
}
return 0;
}
}

Note that the Lua_rawset and lua_settable here are equivalent, just lua_rawset faster. Finally, we call these two functions after loading the LUA script:

Copy Code code as follows:

Writeluaarray (L);
Readluaarray (L);

The output results are:

Copy Code code as follows:

Readluaarray:hehe1
Readluaarray:hehe2
Readluaarray:hehe3
Readluaarray:hehe4

Specialized array Manipulation methods

Because arrays are typically treated as special in the program language, LUA is no exception, and its C API provides another convenient and efficient way to access the elements of an array.

Copy Code code as follows:

void Lua_rawgeti (lua_state *l, int index, int key);
void Lua_rawseti (lua_state *l, int index, int key);

The meanings of the following two parameters are: Index (the index of the table in the stack), key (the indexes of the array in table, subscript from 1) Next, I will demonstrate the use of these two APIs by revamping the above example.

Reading arrays

Because Lua_rawgeti (L,t,key) is equivalent to:

Copy Code code as follows:

Lua_pushnumber (L, key);
Lua_rawget (L, T);

Therefore, our reading code can be rewritten as follows:

Copy Code code as follows:

void Readluaarray (Lua_state *l)
{
Lua_getglobal (L, "array");
int n = Lual_len (L,-1);
for (int i = 1; I <= n; ++i) {
Lua_rawgeti (L, 1, i);
cout<< "Readluaarray:" <<lua_tostring (L,-1) <<endl;
Lua_pop (L, 1);
}
}

Modifying an array

Similarly, Lua_rawset (L,t,key) is equivalent to

Copy Code code as follows:

Lua_pushnumber (L,key); At this time the stack Table->value->key
Lua_insert (l,-2); Stack after call: Table->key->value (Table[key]=value)
Lua_rawset (l,t);

The corresponding code to modify the array can be modified to:

Copy Code code as follows:

int Writeluaarray (lua_state *l)
{
Lua_settop (L, 0);
Lua_getglobal (L, "array");
Make sure that the first function is a table
Lual_checktype (L, 1, lua_ttable);
int n = lual_len (l,1);
for (int i = 1; I <= n; ++i) {
Char buf[256];
sprintf (buf, "hehe%d", I);
Lua_pushstring (L, buf);
Lua_rawseti (L, 1, i);
}
return 0;
}

C + + operations Lua string

Basic string manipulation

The Lua C API manipulation string consists of two operations: a substring (lua_pushlstring) and a string concatenation (Lua_concat). For example, we seek a substring of string s [I,j], which can be expressed as:

Copy Code code as follows:

Lua_pushlstring (L, S + i, j-i + 1);

and Lua_concat (L,n) can be the current stack top of the n elements into a string and splicing, and finally put the results into the top of the stack. For example, we want to define a function mycontact (..., n) to concatenate n strings and N to represent the number of strings, so our code can be written like this:
Copy Code code as follows:

static int l_mycontact (lua_state* l) {
Lual_checktype (L,-1, Lua_tnumber);
int n = lua_tonumber (L,-1);
Lua_pop (L, 1);
Lua_concat (L, N);
return 1;
}

Then we need to register this function into Libs, and finally call this function in Lua:

Copy Code code as follows:

Print (Mylib.mycontact ("Zilong", "Shanren", "Meng Meng", "Da", 4))

The output results are:

Copy Code code as follows:

Zilongshanren Meng Meng da

Format output

When we want to write a format string to LUA, we can use the function

Copy Code code as follows:

const char *lua_pushfstring (lua_state *l, const char *fmt, ...);

In addition, we can also use Lual_buffer, which is the example in the PiL book, which converts the LUA string to uppercase:

Copy Code code as follows:

static int Str_upper (Lua_state *l) {
size_t l;
size_t i;
Lual_buffer b;
const char *s = lual_checklstring (L, 1, &l); Fetching strings from the LUA stack
Char *p = lual_buffinitsize (L, &b, L); Allocates a buffer of the same size as the fetch string
for (i = 0; i < L; i++)
P[i] = ToUpper (Uchar (s[i));
Lual_pushresultsize (&b, L); Converts the result of a buffer to a string
return 1;
}

The more LUA buffer operations functions are as follows:

Copy Code code as follows:

void Lual_buffinit (Lua_state *l, Lual_buffer *b);
void Lual_addvalue (Lual_buffer *b);
void Lual_addlstring (Lual_buffer *b, const char *s, size_t L);
void Lual_addstring (Lual_buffer *b, const char *s);
void Lual_addchar (Lual_buffer *b, char c);
void Lual_pushresult (Lual_buffer *b);

On the use of each function and the meaning of each parameter, you can go to the LUA reference manual up to see, this article will not repeat.

Store LUA Status

In the C function, when we need to save some state in the function, we generally adopt the global variable or static variable. However, if you are interacting with LUA, neither of these methods is desirable. Reason has two: 1. c variables are hard to store in a variety of LUA variables. 2. When multiple LUA stacks exist, they do not take effect. In Lua there are two ways to exist non-local data within a function: Registry and Upvalue.

Registry Way

The register is a LUA global table that can be accessed only in the LUA C API. It can be used to store data between multiple LUA modules. The general way to access a register is:

Copy Code code as follows:

Lua_getfield (L, Lua_registryindex, "Key");

We need to provide a Lua_registryindex "pseudo index" to identify its position in the LUA stack. When we're working on this table, it's best to use a string as key instead of using numbers as key. For more practical use of registry, we'll discuss it in the next article.

Upvalue Way

Upvalue is mainly used to store some private data inside a module or function, which is somewhat similar to the static variable in C language. The specific usage can refer to PIL

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.