目录:

lua与c语言的相互调用

主要参考:

Lua5.3 与C交互学习(一)

其它参考:

快速掌握Lua 5.3

快速掌握Lua 5.3 —— Lua与C之间的交互概览

快速掌握Lua 5.3 —— 从Lua中调用C函数

lua5.3调用C/C++

概要

主要是在linux下编译使用lua,makefile相对来说比较简单,环境比较快速也比较容易搭建。

c调用lua

直接上代码,感觉通过网上资源学习后,练习下代码,很快就明白了大部分原理。

c调用的lua程序c_call_lua.lua:

--- file name: c_call_lua.lua
--- 这个lua程序两个参数,两个返回值
function he(x, y)
        return x*y, x+y
end

注意:这个lua程序两个参数,两个返回值

因为lua与c交互时,参数和返回值的传递都是通过lua中的一个“虚拟栈”进行的。所以c 程序调用lua的he函数时,

要先进行两次入栈操作,传递x,y这两个参数。调用完后,需要进行两次出栈操作,来获取两次的返回值。

调用lua程序的c程序:

/******************************************************************************
 *
 *       Filename:  test.c
 *
 *    Description:  test lua
 *
 *        Version:  1.0
 *        Created:  03/23/2018 03:09:58 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  yangkun (yk)
 *          Email:  [email protected]
 *        Company:  yangkun.com
 *
 *****************************************************************************/
#include <stdio.h>
#include <string.h>

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

int main(int argc, char* argv[])
{
    lua_State *L = luaL_newstate();
        // 加载Lua通用扩展库
    luaL_openlibs(L);
    if(luaL_loadfile(L,"c_call_lua.lua")||lua_pcall(L,0,0,0))  //或luaL_dofile(L,"test.lua")
        printf("error pcall!: %s\n",lua_tostring(L,-1));
    // 前面搭建了运行环境,lua代码写在了test.lua文件中
    // ......
    //

        int ret1=0, ret2=0;
        lua_getglobal(L, "he");
        lua_pushnumber(L, 5);
        lua_pushnumber(L, 6);
        // run the lua program
        // lua_pcall(L, nargs, nresults, 0)
        if(lua_pcall(L, 2, 2, 0) != 0)
                printf("error pcall!:%s\n", lua_tostring(L, -1));
                // if error then push errorinfo in the stack else push results
        /// 提取栈顶数据
        if (!lua_isnumber(L, -1))
                printf("error return!\n");
        else
                ret1 = (int)lua_tonumber(L, -1);

        /// 提取栈顶+1数据
        if (!lua_isnumber(L, -2))
                printf("error return!\n");
        else
                ret2 = (int)lua_tonumber(L, -2);
        printf("get lua function he return value:%d, %d\n", ret1, ret2);


        ///  关闭lua
    lua_close(L);
    return 0;
}

但是有个问题:调用lua函数后,进行了两次出栈操作,但是栈的大小后位置没有变,也就是数据还在栈里面,这个数据之后会被lua释放是吗?检查没有发现内存泄漏

lua掉用c

lua调用c的程序lua程序lua_call_c.lua:

--- filename:lua_call_c.lua
--call he
a, b = he(10, 20)
print(a, b)

--call tt(TTable) return a table
_table=tt()
print(_table)

-- print the table length
print("table len:", #_table)

-- show the table
for k, v in pairs(_table) do
        print(k, v)
        if type(v)=="table" then
                for k, v in pairs(v) do
                        print(k, v)
                end
        end
end

lua返回普通值,返回数组

c程序中函数,获取lua调用的参数,并返回;以程序中创建表并返回给lua程序,lua对表进行相关显示。

lua调用c的c程序:

/******************************************************************************
 *
 *       Filename:  lua_call_c.c
 *
 *    Description:  lua_call_c
 *
 *        Version:  1.0
 *        Created:  03/23/2018 03:47:06 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  yangkun (yk)
 *          Email:  [email protected]
 *        Company:  yangkun.com
 *
 *****************************************************************************/

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

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

// 普通函数
static int he(lua_State* L)
{
        // 从栈中检查参数是否合法并读取参数,
        int a = luaL_checknumber(L,1);
        int b = luaL_checknumber(L,2);

        // 将运算结果返回栈中供lua使用
        lua_pushnumber(L,a*b);
        lua_pushnumber(L,a+b);

        //有2个返回值,也就是入栈了两个值,返回2
        return 2;
}

// 在C++中向lua传递table结构的数据
// 这里的table是:{{"he"},{"li"}}
int TTable(lua_State* L)
{
        // 创建大table
        lua_newtable(L);

        // 大table的key
        lua_pushnumber(L,1); // 1为键
        //第一个小table
        lua_newtable(L);
        // 第一个小table的key,value
        lua_pushnumber(L,1);
        lua_pushstring(L,"he");
        lua_settable(L,-3);
        //第一个小table的成员结束
        lua_settable(L,-3);
        //第二个小table,类似上面的过程
        lua_pushnumber(L,2); // 2为键
        lua_newtable(L);
        lua_pushnumber(L,1);
        lua_pushstring(L,"li");
        lua_settable(L,-3);
        lua_settable(L,-3);
                return 1;  //1个大table
}

int main(int argc, char* argv[])
{
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);  // 加载Lua通用扩展库
    // 将he函数注册成lua的全局函数
    lua_register(L,"he",he);
    lua_register(L,"tt", TTable);
    // if(luaL_loadfile(L,"lua_call_c.lua")/*||lua_pcall(L,0,0,0)*/)
        if(luaL_dofile(L, "lua_call_c.lua"))
        printf("error pcall!: %s\n",lua_tostring(L,-1));
    lua_close(L);
    return 0;
}

多个lua程序

a.lua:

//a.lua
a = 50
local b = 10

h.lua:

//h.lua
dofile("X:/.../a.lua")  //或在同一个目录下时:doflie("a.lua")        require会更好
print(a,b)

lua中: 直接运行h.lua想要调用a.lua中的内容则要在a.lua中运行dofile("X:/.../a.lua") C中两种方法:

最后说下typora是个好东西:

typora.png

typora.png