当前位置:网站首页>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
边栏推荐
- On the value of line height
- Lambda终结操作查找与匹配noneMatch
- Very simple installation and configuration of nodejs
- Advanced Mathematics (Seventh Edition) Tongji University exercises 1-3 personal solutions
- 单片机:EEPROM介绍与操作
- Intervention analysis + pseudo regression
- Single chip microcomputer: d/a output
- OKR和KPI的区别
- UnionPay commerce - merchant statistics service platform
- EGO Planner代码解析----CMakeLists.txt和package.xml
猜你喜欢
Alipay open platform
[test development] automatic test selenium (I)
Very simple installation and configuration of nodejs
Jumpserver installation
单片机:Modbus 通信协议介绍
[test development] automated test selenium (II) -- common APIs for webdriver
[test development] installation of test management tool Zen path
环评图件制作-数据处理+图件制作
单片机:PCF8591 应用程序
单片机:A/D 差分输入信号
随机推荐
Jumpserver: user - system privileged user - Asset - authorization
MCU: RS485 communication and Modbus Protocol
[test development] basic concepts related to testing
Introduction to MCU peripherals: temperature sensor DS18B20
Tencent cloud instant messaging IM
Interpretation of mobile phone private charging protocol
Lambda termination operation Max & min
单片机外设介绍:温度传感器 DS18B20
[Yugong series] June 2022 Net architecture class 080 master cluster and database switching of distributed middleware schedulemaster
手机私有充电协议解读
Summary of meeting between president Ren and scientists and experts in system engineering
Lambda终结操作查找与匹配findFirst
Meaning of different values of margin and padding
Among the four common technologies for UAV obstacle avoidance, why does Dajiang prefer binocular vision
Milliards de données pour déterminer si un élément existe
Solution to failure to download files by wechat scanning QR code
单片机:NEC 协议红外遥控器
GoFrame第四天
Single chip microcomputer: d/a output
Lambda end operation find and match allmatch