Integration of LUA and VC

Source: Internet
Author: User

I have studied lua over the past few days. I mainly focus on the integration between lua and vc and write the code in the VC Host Program, then, call the code of the Host Program in lua (or interface or component, whatever you call it), hoping to use the script to control the behavior of the main program. This is actually an architecture that separates businesses and uses scripts to control them. Some people may call such scripts as business engines and workflows.

Why lua?

Because it is a scripting language that can be very tightly integrated with C/C ++, our program is written in VC ++. The other reason is that it is famous, even WOW uses lua to provide APIs for gamers to modify their game behavior, so I can't find any reason to reject it.

What is Lua? Where can I obtain LUA?

I did not go into details. I searched a lot on the Internet and only talked about its official internet cafe www.lua.org. Here I can find the lua application. I used the version 5.1.4 released by lua, download the source code version.

Integration of LUA and vc mfc?

  • 1. Including LUA: You need to use LUA. Of course, you must first include it in our project. You can use lib/dll or static lib, of course, you can also put the entire lua code into our project and then compile it, Because lua only has several hundred kb and is very small... The method that contains the entire code is described as follows:
  • A) create a project in vc mfc (for example, Dialog base project)
  • B) Go to the file tab page of the project, create a folder, and. c ,. H files are included. Note that there are a few unnecessary files, lua. c. wmain. c. luac. c. After the folder is included, select all. c file, right-click setting and choose Not using precompiler file. Find the file by yourself. After this step is completed, compile it immediately. It should be okay!
  • C) There are two ways to include lua into the project: dynamic library and static lib. You can try it yourself.
  • 2. Include the lua header file somewhere (starting from the MFCLua1Dlg. cpp file) and declare a lua_state pointer, as shown below:

Extern "C"

{

# Include "lua. h"

# Include "lualib. h"

# Include "lauxlib. h"

}

Lua_State * lua;

Call the following code in a proper place (I am in OnInitDialog). The function of this Code is to open some necessary libraries:

Lua = lua_open ();

If (lua)

{

Luaopen_base (lua );

Luaopen_table (lua );

Luaopen_string (lua );

Luaopen_math (lua );

Luaopen_debug (lua );

// Luaopen_io (lua );

}

When lua is used up, call the following sentence to close the lua database:

Lua_close (lua );

Now, lua has completely become a part of our program. Let's compile it to see if it can be passed...

Interaction between LUA and MFC?

After Lua becomes a part of our program, we need to use it. Remember that our goal is to use a script program to control the execution process of our host program. We need to complete two steps, first, use the mfc program to call the lua function, and second, use lua to call the mfc function. The following content may be difficult for beginners to understand, I will try to put it simply...

1. mfc calls the lua function. A StackDump function is used here to address the issue of the Interaction stack between the main program and lua. The following describes the issue of the Interaction stack.

First, we use NotePad to create a test. lua. The content is an addition function:

Function add (x, y)

Return x + y;

End

Then, call it in VC, the following code. when reading this code, ignore the StackDump function. You only need to know that it is a function that outputs the content of the Interaction stack between lua and vc, by the way, you can create a button's click function and put the code in it:

StackDump (lua );

LuaL_dofile (lua, "test. lua"); // parse the lua File

StackDump (lua );

Lua_getglobal (lua, "add"); // obtain a global label add. At the same time, the add function is pushed to the stack.

StackDump (lua );

Lua_pushnumber (lua, 1); // press the first parameter into the stack.

StackDump (lua );

Lua_pushnumber (lua, 2); // The second parameter pressure Stack

StackDump (lua );

// Lua_call (lua, 2, 1 );

If (lua_pcall (lua, 2, 1, 0 )! = 0) // execute the add function

{

AfxMessageBox ("lua_pcall error! ");

Return;

}

StackDump (lua );

Int d = (int) lua_tonumber (lua,-1); // After the function is executed, the execution result is pushed to the stack. Therefore, the result value is obtained from the top number, -1 refers to the value of the top stack.

CString str;

Str. Format ("% d", d );

AfxMessageBox (str );

StackDump (lua );

Lua_pop (lua, 1); // clear the value from the stack, pop (pop) A Value

StackDump (lua );

After analyzing this code, we probably know that the process of calling the lua function is: dofile --> function name pressure Stack --> parameter pressure stack in sequence --> lua_pcall execution (execution result pressure stack) --> retrieve the execution result (if there are multiple results, retrieve multiple results from the stack ...), In this way, we can easily call the functions in lua. In fact, we need to know what happened in the stack...

2. lua calls the MFC function. For example, if we want to call a Msg function in lua, a window will pop up to display the string we want to display, and the return value will be 1 "MsgOK! "String.

The lua file is like this. The first sentence is to call the Msg function, and the second sentence is to test whether the returned string is "MsgOK! ":

C = Msg ("123 ");

Msg (c );

In the MFC program:

First, write a function to be exported. Many articles call it glue function ):

Static int Msg (lua_State * L)

{

Const char * s1 = luaL_checkstring (L, 1); // test whether the first parameter is in the string format and obtain this string

StackDump (L );

MessageBox (NULL, s1, "caption", MB_ OK );

Lua_pop (lua, 1); // clear the string in the stack

StackDump (L );

Lua_pushlstring (L, "MsgOK! ", 6); // press the return value into the stack

// The number of returned values

Return 1;

}

Then export the function as follows:

Lua_pushcfunction (lua, Msg );

Lua_setglobal (lua, "Msg ");

Then execute the lua file just now. Remember to execute lua_open () first:

LuaL_dofile (lua, "test. lua ");

The result of running is to jump out of two messageboxes consecutively. The first is 123, and the second is "MsgOK! ", Indicates that the returned string is received by lua. If the second line of lua does not receive its return value, the returned value is automatically discarded.

If you need to return multiple values, we should take the following sentence:

Lua_pushlstring (L, "MsgOK! ", 6); // press the return value into the stack

// The number of returned values

Return 1;

Changed:

Lua_pushlstring (L, "MsgOK! ", 6); // press the return value into the stack

Lua_pushlstring (L, "haha! ", 5); // press the return value into the stack

// The number of returned values

Return 2;

In this way, we can get two return values in the lua file as follows:

C, d = Msg ("123 ");

Then c and d are respectively "MsgOK! "And" haha! "Two strings. This automatic mechanism is more convenient to use.

3. Interactive Stack

The above two calls are actually applicable to the lua stack, so we need to understand the concept of the Interaction stack between lua and vc (what is the stack? Please refer to the data structure book ...) Lua and vc interact through this stack. The access functions of this stack include lua_gettop, lua_settop, lua_tostring, lua_toXXX, and so on. We need to know when a function call occurs, what happened in the stack. I used a StackDump function above. When we call it, we can clearly see what happened in the stack.

First, we need to know that the number from the top of the stack is-1,-2, and the number from the bottom of the stack is 1, 2.

If lua_gettop (L, 1) is used, the first element at the bottom of the stack is obtained. Lua_gettop (L,-1) is the first element to get the top of the stack. Lua_pop () (L, 1) is to pop up an element at the top of the stack. lua_pop () (L, 2) is to pop up two elements at the top of the stack.

Okay, I wrote a pass, and finally the implementation of this StackDump function:

Int StackDump (lua_State * L)

{

Int nTop = lua_gettop (L); // obtain the number of elements in the stack. Stack top position.

OutputDebugString ("The Length of stack is % d/n", nTop); // The top position of The output stack.

For (int I = 1; I <= nTop; ++ I)

{

Int t = lua_type (L, I );

OutputDebugString ("% s:", lua_typename (L, t); // here, typename converts enumeration of the type into a string and is the type name. It is not the position in the stack.

Switch (t)

{

Case LUA_TNUMBER:

OutputDebugString ("% f", lua_tonumber (L, I ));

Break;

Case LUA_TSTRING:

OutputDebugString ("% s", lua_tostring (L, I ));

Break;

Case LUA_TTABLE:

// OutputDebugString ("% s/n", lua_tostring (L, I ));

Break;

Case LUA_TFUNCTION:

// OutputDebugString ("% s/n", lua_tostring (L, I ));

Break;

Case LUA_TNIL:

OutputDebugString ("Is NULL ");

Break;

Case LUA_TBOOLEAN:

OutputDebugString ("% s", lua_toboolean (L, I )? "True": "false ");

Break;

Default:

Break;

}

OutputDebugString ("/n ");

}

Return 0;

}

This article focuses on the integration of lua and VC, compilation of LUA source code and VC project together, VC calls LUA's code, and LUA calls VC's code, return values and multiple return values, interactive stacks, and Element Information in the output interactive stack. The next article will talk about how to avoid blocking scripts, lua and multithreading usage, and so on.

 

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.