当前位置:网站首页>Call C function in Lua

Call C function in Lua

2022-06-13 04:00:00 Python's path to becoming a God

https://www.cnblogs.com/sifenkesi/p/3876745.html

https://blog.csdn.net/liu943367080/article/details/90909005

Lua Use a virtual stack to give C Pass a value or from C Get value

Lua Use a virtual stack to give C Pass a value or from C Get value . whenever Lua call C function , Will get a new stack , The stack initially contains all the calls C The parameter values required by the function (Lua Pass to C Function call arguments ), also C After the function is executed , Will push the return value onto this stack (Lua Get... From it C Function call results ).

Related to this C API There are several important definitions as follows :

(1)typedef struct lua_State lua_State;
  lua virtual machine ( Or interpreter ), You can think of it as one thread, And a complete Lua The execution state of the virtual environment .

(2)typedef int (*lua_CFunction) (lua_State *L);

It can be Lua Called C Functions must be this rule . Function returns int Value representation C The number of returned values of the function .

(3)void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);
   Will a C Closure stack ;
   First of all, will upvalues Press the stack in turn , And then call the function. , take c Function stack , And will n individual upvalues Out of the stack ;
   Parameters fn:C A function pointer
   Parameters n: Functionally correlated upvalue The number of .

(4)void lua_pushcfunction (lua_State *L, lua_CFunction f);
   take C Function stack ;
   Receive one C Pointer parameter of function , And then put a Lua.function Object stack of type .

(5)void lua_register (lua_State *L, const char *name, lua_CFunction f);
   register C The function is 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 ;
   Parameters l:luaL_Reg list , Record the function information to be registered , Be careful , The list is shown in {NULL, NULL} ending ;
  nup Parameters :upvalue The number of , If not for 0, All registered functions share these upvalues;
   First the table Pressing stack , And then upvalues Press the stack in turn , Then call this function to register function. . After registration upvalues Will stack out .
   Be careful :luaL_register Functions are no longer used , In its place luaL_setfuncs, Because this function does not create global variables .

typedef struct luaL_Reg { 
     const char *name; lua_CFunction func; } luaL_Reg;

Lua You can call C The ability of functions will be greatly improved Lua Scalability and availability of . For some operating system related functions , Or modules that require high efficiency , We can go through C Function to implement , After that Lua Call the specified C function . For those who can be Lua Called C Function , Its interface must follow Lua Required form , namely typedef int (lua_CFunction)(lua_State L). Just a quick explanation , The function type contains only one representation Lua The pointer to the environment as its only parameter , The implementer can further obtain Lua The parameters actually passed in the code . Return value is integer , It means that we should C The function will return to Lua The number of return values of the code , If there is no return value , be return 0 that will do . It should be noted that ,C The function cannot directly return the real return value to Lua Code , But through the virtual stack Lua Code and C Between call parameters and return values of functions . Here we will introduce two Lua call C The rules of functions .

1. C Functions as part of an application

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

// stay Lua Called C Register function .
static int add2(lua_State* L)
{ 
    
    // Check whether the parameters in the stack are legal ,1 Express Lua The first parameter when calling ( From left to right ), And so on .
    // If Lua The parameter passed by the code when calling is not number, This function will report an error and terminate the execution of the program .
    double op1 = luaL_checknumber(L,1);
    double op2 = luaL_checknumber(L,2);
    // Push the result of the function onto the stack . If there are multiple return values , You can push it into the stack many times here .
    lua_pushnumber(L,op1 + op2);
    // The return value is used to prompt the C The number of return values of the function , That is, the number of return values pushed into the stack .
    return 1;
}

// The other is waiting for Lua Called C Register function .
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 Lua Global function variable of , The first string parameter is Lua Code 
    // Calling C The global function name to use when using the function , The second parameter is the actual C Pointer to function .
    lua_register(L, "add2", add2);
    lua_register(L, "sub2", sub2);
    // After registering all C After the function , Can be in Lua Use these registered in the code block of C Function .
    if (luaL_dostring(L,testfunc))
        printf("Failed to invoke.\n");
    lua_close(L);
    return 0;
}

2. C The function library becomes Lua Module

Will include C Function code generation library file , Such as Linux Of so, or Windows Of DLL, And copy it to Lua The current directory where the code is located , Or is it LUA_CPATH The directory the environment variable points to , For convenience Lua The parser can locate them correctly . In my current Windows In the system , I will be the copy To "C:\Program Files\Lua\5.1\clibs", It's all about Lua Callable C library . See the following C Language code and key comments :

#include <stdio.h>
#include <string.h>

extern "C"
{ 
    
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}

#if defined(_WIN32) || defined(_WIN64)
#define _DLLExport _declspec(dllexport)
#else
#define _DLLExport 
#endif
//  It should be noted that , The function must be C The form of is derived , therefore extern "C" Is a must .
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;
}
//  Must be {NULL, NULL} ending 
static luaL_Reg registerInfo[] = { 
    
    { 
    "add", add},
    { 
    "sub", sub},
    { 
    NULL, NULL}
};

//  The C The entry function of the library //  Function name must be luaopen_xxx, among xxx Express library name .Lua Code require "xxx" It needs to be matched .
extern "C" _DLLExport int luaopen_CLibraryForLua(lua_State * L)
{ 
    
    luaL_newlib(L, registerInfo);

    //  The top line is equivalent to the next two lines 
    // luaL_newlibtable(L, registerInfo);
    // luaL_setfuncs(L, registerInfo, 0);

    return 1;
}

See the following Lua Code :

require "CLibraryForLua"  -- Specify the package name 
 
-- In the call , Must be package.function
print(CLibraryForLua.add(1.0,2.0))
print(CLibraryForLua.sub(20.1,19))

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

Lua Call in C function

https://blog.csdn.net/liu943367080/article/details/90909005

Lua You can call C The ability of functions will be greatly improved Lua Scalability and availability of .

For some operating system related functions , Or modules that require high efficiency , We can go through C Function to implement , After that Lua Call the specified C function .

For those who can be Lua Called C Function , Its interface must follow Lua Required form , namely typedef int (lua_CFunction)(lua_State L).

Just a quick explanation , The function type contains only one representation Lua The pointer to the environment as its only parameter , The implementer can further obtain Lua The parameters actually passed in the code . Return value is integer , It means that we should C The function will return to Lua The number of return values of the code , If there is no return value , be return 0 that will do . It should be noted that ,C The function cannot directly return the real return value to Lua Code , But through the virtual stack Lua Code and C Between call parameters and return values of functions .

The sample code :

// testlua.cpp :  Defines the entry point for the console application .
//
#include <stdio.h>
#include <string.h>
#include <math.h>
 
extern "C"
{ 
    
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
}
 
// stay Lua Called C Register function 
static int add2(lua_State* L)
{ 
    
    // Check whether the parameters in the stack are legal ,1 Express Lua The first parameter when calling ( From left to right ), And so on .
    // If Lua The parameter passed by the code when calling is not number, This function will report an error and terminate the execution of the program .
    double op1 = luaL_checknumber(L,1);
    double op2 = luaL_checknumber(L,2);
    // Push the result of the function onto the stack . If there are multiple return values , You can push it into the stack many times here .
    lua_pushnumber(L,op1 + op2);
    // The return value is used to prompt the C The number of return values of the function , That is, the number of return values pushed into the stack .
    return 1;
}
 
// stay Lua Called C Register function .
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;
}
 
// stay Lua Called C Register function .
static int l_sin (lua_State *L) { 
    
    double d = lua_tonumber(L, 1); /* get argument */
    lua_pushnumber(L, sin(d)); /* push result */
    return 1; /* number of results */
}
 
int main(int argc, char* argv[])
{ 
    
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);
 
    // Register the specified function as Lua Global function variable of , The first string parameter is Lua Code 
    // Calling C The global function name to use when using the function , The second parameter is the actual C Pointer to function .
    lua_register(L, "add2", add2);
    lua_register(L, "sub2", sub2);
    lua_register(L, "l_sin", l_sin);

     // After registering all C After the function , Can be in Lua Use these registered in the code block of C Function .
    auto res = luaL_dofile(L,"test.lua"); // Call the script to return the running result 
    if(res != 0){ 
     // Determine what went wrong 
        if(lua_isstring(L,-1)){ 
    
            auto msg = lua_tostring(L,-1);
            printf("load script failed: %s\n", msg); // Print error message 
            lua_pop(L,1);
        }
    }
    //if (luaL_dostring(L,testfunc))
    // printf("Failed to invoke.\n");
 
    //const char *buf = "print('Hello World')";
    //luaL_dostring(L,buf);
 
    lua_close(L);
    return 0;
}

test.lua

function show()  
    print("helloworld") 
    print(add2(1.0,2.0)) 
    print(sub2(20.1,19))
    print(l_sin(1))
end  

show() 

Due to the use of auto keyword , Compilation needs to be added C++11 characteristic

g++ testlua.cpp -o testlua -llua -lm -ldl -std=c++11

Running results :
 Insert picture description here

Lua call c modular

https://blog.csdn.net/weixin_41966991/article/details/88847756

Qt call Lua Script compilation options note

Qt Project files are automatically added C++11 characteristic , Just add and lua Relevant can

INCLUDEPATH += /usr/local/include

LIBS += -L/usr/local/lib -llua  -lm -ldl

Be careful :-lm -ldl It can't be less , Otherwise, the report will be wrong .
 Insert picture description here
And QtScript comparison ,Lua And Qt How easy it is ?

I prefer Lua and ECMAScript. however , To write Lua Binding is very simple ,QtScript The level of integration provided can provide many functions out of the box . This includes binding to the built-in QObject Derived classes and from QObject and / or QScriptClass Inherit your own class . therefore , If you just want to be independent of Qt Function to write scripts or configure your own classes , Then I will choose Lua. however , If you mainly want to work with QObject To interact with , that QtScript Will greatly reduce your initial development time . The best of both worlds is to use the spare QScriptEngine For the Lua Script options .

QtScript routine

https://blog.csdn.net/bbjjqq/article/details/6164291?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164586026616780261916866%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=164586026616780261916866&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-2-6164291.pc_search_result_positive&utm_term=QtScript&spm=1018.2226.3001.4187

QtScript Script and C++ Code interaction

https://blog.csdn.net/zgrjkflmkyc/article/details/45822557

Qt Simple packaging QtScript, Easy to use

https://blog.csdn.net/gfgfd12315/article/details/115340118?spm=1001.2101.3001.6650.8&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-8.pc_relevant_paycolumn_v3&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-8.pc_relevant_paycolumn_v3&utm_relevant_index=13

QT Of QScriptEngine The use of the class

https://blog.csdn.net/it_xiangqiang/article/details/111572639?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164586060116780255252391%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=164586060116780255252391&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-111572639.pc_search_result_positive&utm_term=QScriptEngine&spm=1018.2226.3001.4187

原网站

版权声明
本文为[Python's path to becoming a God]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202280526440165.html