当前位置:网站首页>Call C function in Lua
Call C function in Lua
2022-06-13 04:00:00 【Python's path to becoming a God】
Lua Call in C function
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 :
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 .
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
QtScript Script and C++ Code interaction
https://blog.csdn.net/zgrjkflmkyc/article/details/45822557
Qt Simple packaging QtScript, Easy to use
QT Of QScriptEngine The use of the class
边栏推荐
- SCM signal generator program
- Introduction to MCU peripherals: temperature sensor DS18B20
- SCM: introduction and operation of EEPROM
- Flex layout
- Billions of data to determine whether the element exists
- Answer private message @ Tiantian Wx //2022-6-12 C language 51 single chip microcomputer led analog traffic light
- 无人机避障四种常见技术中,为何大疆首选双目视觉
- [test development] use case
- footstep
- 高等数学(第七版)同济大学 习题1-2 个人解答
猜你喜欢
随机推荐
无人机避障四种常见技术中,为何大疆首选双目视觉
Advanced Mathematics (Seventh Edition) Tongji University exercises 1-3 personal solutions
单片机:NEC 协议红外遥控器
Intervention analysis + pseudo regression
GoFrame第四天
Goframe day 5
Ego planner code analysis ----cmakelists Txt and package xml
MSG messages in ROS
Field * doesn't have a default value problem
[test development] advanced part - Classification of various test technologies
ROS topics and nodes
十亿数据量 判断元素是否存在
Redis-HyperLogLog-基数统计算法
5G China unicom AP:B SMS ASCII 转码要求
单片机:PCF8591硬件接口
ET框架-22 创建ServerInfo实体及事件
【Web】Cookie 和 Session
Billions of data to determine whether the element exists
Lambda end operation reduce merge
Cache read / write -- write