Integrate Lua into the MFC code

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, select not using precompiler file, right-click vs2008. CPP file, ---> properties ----> C/C ++ -----> pre-compiled header -----> Create/use pre-compiled header -----> select: compile immediately after this step without using the pre-compilation header. 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 purpose 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); well, until now, lua has completely become a part of our program. 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, and then call it in VC. The following code shows the code, ignore the stackdump function first. 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 click function for the button and then 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, add function stack stackdump (LUA); lua_pushnumber (Lua, 1); // press the first parameter into the stack stackdump (LUA); lua_pushnumber (Lua, 2); // The second parameter 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); // The execution result is pushed to the stack after the function is executed, therefore, the result value is obtained at the top, and-1 is the cstring STR; Str. format ("% d", d); afxmessagebox (STR); stackdump (LUA); lua_pop (Lua, 1); // clear the value from the stack, pop (pop up) A value stackdump (LUA); analyze this code and we will 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 execution results (if there are multiple, retrieve multiple ones 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, it is like this: 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 the stackdump (l); MessageBox (null, S1, "caption", mb_ OK); lua_pop (Lua, 1 ); // clear the stackdump (l); lua_pushlstring (L, "msgok! ", 6); // press the return value into the stack // This Return Value refers to the number of returned values return 1;} Then export this function, as follows: lua_pushcfunction (Lua, MSG); lua_setglobal (Lua, "MSG"); then execute the Lua file just now. Remember to run lua_open () First: lual_dofile (Lua, "test. lua "); the running result is two consecutive messageboxes, 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 need to put the following sentence: lua_pushlstring (L, "msgok! ", 6); // press the returned value into the stack. // the return value refers to the number of returned values. Return 1; changed to: lua_pushlstring (L," msgok! ", 6); // press the returned value into the stack lua_pushlstring (L," haha! ", 5); // press the returned value into the stack // This Return Value refers to 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 "msgok! "And" haha! "Two strings. This automatic mechanism is more convenient to use. 3. The two calls on the interactive Stack are actually useful to the Lua stack. We need to understand the concept of the interactive 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. Well, I wrote a pass and finally realized the stackdump function: int stackdump (lua_state * l) {int ntop = lua_gettop (l); // get the number of elements in the stack. Stack top position. Outputdebugstring ("the length of stack is % d/N", ntop); // output stack top position for (INT I = 1; I <= ntop; ++ I) {int T = lua_type (L, I); outputdebugstring ("% s:", lua_typename (L, t); // here, typename converts the enumerated type into a string, yes. 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_to Boolean (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.