美文网首页
Lua与C++如何相互交互?

Lua与C++如何相互交互?

作者: 码上述Andy | 来源:发表于2022-03-03 06:22 被阅读0次

    Lua与C++如何相互交互

    通过lua虚拟栈隔离Lua和C/C++类型和彼此内存的差异来实现数据及函数互相调拥。
    1.相互通信:
    C++与Lua基于lua虚拟栈进行数据交换

    lua stack_zw.png

    2.通信流程如下:
    1).C++与lua通信流程:
    C++、Lua示例代码:

    test.cpp 文件
     lua_State*  L = luaL_newstate();
     luaL_openlibs(lstate);
    1.lua_getglobal("mTable");
    2.lua_pushstring(L, "name");
    int ret = lua_pcall(L, 1, 0, 0);
    3.lua_gettable(L, -2);
    4.lua_tostring(L, -1);
    
    test.lua 文件
    1.a = 1
    2.mTable = {name = "zw", num = 123}
    3.function f() 
          print(a) 
       end
    
    stack_zw.png

    **2).Lua与C通信流程:
    Lua、C源码示例:

    lua_CFunction:
    static int str_find (lua_State *L) {
      return str_find_aux(L, 1);
    }
    luaL_Reg数组:
    static const luaL_Reg strlib[] = {
      {"find", str_find},
      {NULL, NULL}
    };
    入栈相关:
    LUAMOD_API int luaopen_string (lua_State *L) {
      luaL_newlib(L, strlib);
      createmetatable(L);
      return 1;
    }
    添加到lua全局table中:
    LUALIB_API void luaL_openlibs (lua_State *L) {
      const luaL_Reg *lib;
      /* "require" functions from 'loadedlibs' and set results to global table */
      for (lib = loadedlibs; lib->func; lib++) {
        luaL_requiref(L, lib->name, lib->func, 1);
        lua_pop(L, 1);  /* remove lib */
      }}
    栈上弹出一个值,并将其设为全局table变量 modname 的值。
    LUALIB_API void luaL_requiref (lua_State *L, const char *modname,
                                   lua_CFunction openf, int glb) {
     ...
      if (glb) {
        lua_pushvalue(L, -1);  /* copy of module */
        lua_setglobal(L, modname);  /* _G[modname] = module */
      }
    }
    
    local str = "zwenzhou"
    function func()
    print(string.find(str, "z"))  -- find方法就是luaL_Reg结构体数组“find”对应的str_find C函数的具体实现。
    end
    
    stack2_zw.png

    业务实现具体可参照lua源码init.c 库初始化方式,首先创建C闭包(Lua需要调用的宿主函数)并把这个 C (cfunction)闭包压到栈上同时设置到Lua全局table中,Lua通过创建对应的luaL_Reg结构体name(理解为闭包key)对应的lua_CFunction(函数指针),即可访问栈中的lua_CFunction,最终达到Lua访问C++的目的。Lua不能随意访问宿主(C/C++)函数,前提必须有“注册”(个人理解是出于安全考虑)。

    3.综述:
    通过这个lua虚拟栈作桥梁,当C/C++想调用lua中一个值时,Lua将数值压入lua虚拟栈中,然后通过lua提供api操作栈来读取栈顶的值。

    相关文章

      网友评论

          本文标题:Lua与C++如何相互交互?

          本文链接:https://www.haomeiwen.com/subject/liderrtx.html