Call the C function in Lua

Source: Internet
Author: User

Lua uses a virtual stack to pass values to or obtain values from C.Every time Lua calls the C function, a new stack is obtained.The stack initially contains all the parameter values required to call the C function (the call parameters that Lua passes to the C function), and after the C function is executed, the return value is pushed into this stack (LUA obtains the C function call result from it ).

The related c api has several important definitions as follows:

(1) typedef struct lua_state;
The Lua Virtual Machine (or interpreter) can be understood as a thread and the execution status of a complete Lua virtual environment.

(2) typedef int (* lua_cfunction) (lua_state * l );

All C functions that can be called by Lua must be such a rule. The Int value returned by the function indicates the number of values returned by the C function.

  (3) void lua_pushcclosure (lua_state * l, lua_cfunction FN, int N );
Apply a C closure to the stack;
First, the upvalues is pushed to the stack in sequence, then the function is called, the C function is pressed to the stack, and N upvalues are pushed out of the stack;
FN: C function pointer
Parameter N: Number of upvalue associated with the function.

  (4) void lua_pushcfunction (lua_state * l, lua_cfunction F );
Pressure the C function stack;
Receives the pointer parameter of a C function, and then stacks an object of the Lua. function type.

  (5) void lua_register (lua_state * l, const char * Name, lua_cfunction F );
Register the C function as a global variable;
# Define lua_register (L, N, f) (lua_pushcfunction (L, F), lua_setglobal (L, n ))

  (6) void lual_setfuncs (lua_state * l, const lual_reg * l, int NUP );
Register the function to the table at the top of the stack;
Parameter L: lual_reg list, which records the information of the function to be registered. Note that the list ends with {null, null;
Nup parameter: Number of upvalue. If it is not 0, all registered functions share these upvalues;
First, press table to stack, then press upvalues to stack in sequence, and then call this function for function registration. After registration, upvalues will exit the stack.
Note: The lual_register function is no longer used. It is replaced by lual_setfuncs, because this function does not create global variables.

Typedef struct lual_reg {const char * Name; lua_cfunction func;} lual_reg;

Lua's ability to call C functions greatly improves Lua's scalability and availability. For some functions related to the operating system or modules with high efficiency requirements, we can use the C function, and then call the specified C function through Lua. For C functions that can be called by Lua, the interface must follow the Lua requirement, that is, typedef int (* lua_cfunction) (lua_state * l ). This function type only contains a pointer that represents the Lua environment as its unique parameter. The implementer can use this pointer to further obtain the actually passed parameters in the Lua code. The return value is an integer, indicating the number of values that the C function will return to Lua code. If no value is returned, return 0. It should be noted that the C function cannot directly return the real return value to the Lua code, but transmits the call parameters and return values between the Lua code and the C function through the Virtual stack. Here we will introduce two Lua rules for Calling C functions.

  1. c functions as part of the application

# Include <stdio. h> # include <string. h> # include <Lua. HPP> # include <lauxlib. h> # include <lualib. h> // The C registration function to be called by Lua. Static int Add2 (lua_state * l) {// check whether the parameters in the stack are valid. 1 indicates the first parameter (from left to right) for Lua calling, and so on. // If the parameter passed by the Lua code during the call is not a number, this function will report an error and terminate the program execution. Double OP1 = lual_checknumber (L, 1); double OP2 = lual_checknumber (L, 2); // press the function result into the stack. If there are multiple return values, you can press them into the Stack multiple times. Lua_pushnumber (L, OP1 + OP2); // the return value is used to indicate the number of returned values of the C function, that is, the number of returned values pushed into the stack. Return 1;} // another c registration function to be called by Lua. Static int sub2 (lua_state * l) {double OP1 = lual_checknumber (L, 1); double OP2 = lual_checknumber (L, 2); lua_pushnumber (L, OP1-OP2 ); return 1;} const char * testfunc = "Print (Add2 (1.0, 2.0) print (sub2 (20.1, 19)"; int main () {lua_state * l = lual_newstate (); lual_openlibs (l); // register the specified function as a global function variable of Lua, the first string parameter is Lua code // The global function name used to call the C function, and the second parameter is the pointer of the actual C function. Lua_register (L, "Add2", Add2); lua_register (L, "sub2", sub2); // After registering all the C functions, you can use these registered c Functions in the Lua code block. If (lual_dostring (L, testfunc) printf ("failed to invoke. \ n"); lua_close (l); Return 0 ;}

2. c function library becomes the Lua Module
Copy the library files containing C functions, such as Linux So or Windows DLL, to the current directory where the Lua code is located, or to the directory pointed to by the lua_cpath environment variable, so that the Lua parser can locate them correctly. In my current Windows system, I copied it to "C: \ Program Files \ Lua \ 5.1 \ clibs \", which contains all the C libraries that Lua can call. See the following C language code and key notes:

# Include <stdio. h> # include <string. h> # include <Lua. HPP> # include <lauxlib. h> # include <lualib. h> // The C function to be registered. The Declaration Form of this function is provided in the preceding example. // It must be noted that the function must be exported in the form of C, so extern "C" is required. // The function code is the same as the previous example. Extern "C" int add (lua_state * l) {double OP1 = lual_checknumber (L, 1); double OP2 = lual_checknumber (L, 2); lua_pushnumber (L, OP1 + OP2); return 1;} extern "C" int sub (lua_state * l) {double OP1 = lual_checknumber (L, 1); double OP2 = lual_checknumber (L, 2); lua_pushnumber (L, OP1-OP2); return 1;} // The first field of the lual_reg struct is a string, which is used to notify Lua of the name of the function during registration. // The first field is the c function pointer. // The two fields of the last element in the struct array are null, prompting that the Lua registration function has reached the end of the array. Static lual_reg mylibs [] = {"add", add}, {"sub", sub}, {null, null}; // the unique entry function of the C library. The function signature is equivalent to the above registered function. See the following description: // 1. We can simply understand this function as a factory function of the module. // 2. The function name must be luaopen_xxx, where xxx indicates the library name. The Lua Code require "XXX" needs to correspond to it. // 3. In the lual_register call, the first string parameter is the module name "XXX", and the second parameter is the array of the function to be registered. // 4. It should be emphasized that all codes that require "XXX" must be consistent, regardless of C or Lua. This is the Lua Convention. // otherwise, the Code cannot be called. Extern "C" _ declspec (dllexport) int luaopen_mytestlib (lua_state * l) {const char * libname = "mytestlib"; lual_register (L, libname, mylibs); return 1 ;}

See the following Lua code:

Require "mytestlib" -- specify the package name -- it must be package. functionprint (mytestlib. Add (1.0, 2.0) print (mytestlib. sub (20.1, 19 ))

  

Reference: http://www.cnblogs.com/stephen-liu74/archive/2012/07/23/2469902.html

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.