Table of Contents

Lua和C协作

Lua和C(C++)的交互,以下是拿C++举的例子

问题:栈内的元素应该在何时被谁清理呢?需要手动调用pop清理吗?

每一个函数都有自己的栈,当一个C/C++函数把返回值压入Lua栈以后,该栈会自动被清空。

C++调用Lua

基础

下载Lua的源码包,把所有的源文件和头文件添加到C++工程里,Lua的源文件里面有2处main函数的定义,全部注释掉,从自己的main开始,编译

使用:
关于代码中的extern “C”,看这里:命名修饰

#include <algorithm>
 
extern "C"
{
#include "LuaSource/lua.h"
#include "LuaSource/lualib.h"
#include "LuaSource/lauxlib.h"
}
 
int main()
{
    lua_State* L = luaL_newstate(); // L相当于一个Lua的虚拟机?
    luaL_openlibs(L);
    int Ret = luaL_dofile(L, "Lua/Hello.lua"); // 写Lua文件的路径
    lua_close(L);
 
    return 0;
}
print('Hello from Lua')

正常的话现在已经可以运行了

进阶

C++调用Lua

Lua调用C

直接调用

环境配置方式和上面一样

#include <algorithm>
#include <cstdio>
 
extern "C"
{
#include "LuaSource/lua.h"
#include "LuaSource/lualib.h"
#include "LuaSource/lauxlib.h"
}
 
const char* LuaFileName = "MainLua.lua";
 
int range_sum(int l, int r)
{
    int Sum = 0;
    for (int i = l;i <= r;i += 1)
    {
        Sum += i;
    }
    return Sum;
}
 
// 需要被Lua调用的函数
// C++端的函数要按照这个标准来写,一个int返回值,一个lua_State*参数
static int lua_range_sum(lua_State *L)
{
    // 读取Lua端压入栈的参数,注意理清楚顺序
    int l = (int)lua_tonumber(L, -2);
    int r = (int)lua_tonumber(L, -1);
 
    // 把返回值压入栈内
    lua_pushnumber(L, range_sum(l, r));
 
    // 注意这个int返回值不能随便给
    return 1; // 一定需要一个int返回值,这个值表示返回值的个数,也就是向栈内压入了几个值
}
 
int main()
{
    lua_State* L = luaL_newstate();
    luaL_openlibs(L);
    luaL_dofile(L, LuaFileName);
 
    // 注册函数
    // 在Lua端可以直接调用range_sum
    lua_register(L, "range_sum", lua_range_sum);
 
    printf("C++: [1,10] = %d\n", range_sum(1, 10));
 
    lua_getglobal(L, "LuaMain");
    lua_call(L, 0, 0); // 执行LuaMain函数
 
    lua_close(L);
 
    return 0;
}
function LuaMain()
    print('This is Lua Main')
 
    print('Lua: [1,10] = '..range_sum(1, 10))
end
C++: [1,10] = 55
This is Lua Main
Lua: [1,10] = 55.0

封装成DLL

Lua加载动态链接库