zoukankan      html  css  js  c++  java
  • C模块回调Lua函数的两种方法

     

    作者:ani_di
    版权所有,转载务必保留此链接 http://blog.csdn.net/ani_di

    C模块回调Lua函数的两种方法

    lua和C通过虚拟栈这种交互方式简单而又可靠,缺点就是C做栈平衡稍微会多写一点代码。 今天分享学到的C模块回调Lua函数的两种方法,都是炒冷饭,大侠勿喷。

    1. C保存函数对象

    C模块可以通过注册表保存Lua里面的对象,等适当时候取出再调用即可。

    static int lua_callback = LUA_REFNIL;
    
    static int setnotify(lua_State *L)
    {
      lua_callback = luaL_ref(L, LUA_REGISTRYINDEX);
      return 0;
    }
    
    static int testnotify(lua_State *L)
    {
      lua_rawgeti(L, LUA_REGISTRYINDEX, lua_callback);
      lua_call(L, 0, 0);
    }

    luaL_ref把栈顶的值取出,放到指定的tabel中,然后返回一个索引(目测是数组的index)。 lua_rawgeti把之前保存的function对象取出,再由lua_call调用。

    function callback(  )
        print "Callback"
    end
    
    cb.setnotify(callback)
    cb.testnotify()

    2. C访问Lua全局环境

    第二种方法更简便,C直接调用Lua中的函数,就像Lua调用C一样

    static int testenv(lua_State *L)
    {
      lua_getglobal(L, "defcallback");
      lua_call(L, 0, 0);
    }

    该方法的缺点就是如果C模块独立编写,方法名就不太灵活。 用这种方法一般会在Lua端再封装一层,以隔离全局环境。

    3. 完整例子

    cb.c

    #include <stdio.h>
    #include <stdlib.h>
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"
    
    static int lua_callback = LUA_REFNIL;
    
    static int setnotify(lua_State *L)
    {
      lua_callback = luaL_ref(L, LUA_REGISTRYINDEX);
      return 0;
    }
    
    static int testnotify(lua_State *L)
    {
      lua_rawgeti(L, LUA_REGISTRYINDEX, lua_callback);
      lua_call(L, 0, 0);
    }
    
    static int testenv(lua_State *L)
    {
      lua_getglobal(L, "defcallback");
      lua_call(L, 0, 0);
    }
    
    static const luaL_Reg cblib[] = {
      {"setnotify", setnotify},
      {"testnotify", testnotify},
      {"testenv", testenv},
      {NULL, NULL}
    };
    
    int luaopen_cb(lua_State *L)
    {
      luaL_register(L, "cb", cblib);
      return 1;
    }

    test.lua

    require("cb")
    
    function callback(  )
      print "Callback"
    end
    
    function defcallback()
      print "Predef callback"
    end
    
    cb.setnotify(callback)
    cb.testnotify()
    print "Done"
    cb.testenv()
  • 相关阅读:
    AOP与IOC的概念(即spring的核心)
    Md5密码加密的使用
    all-mobile.js
    config.js
    login.css
    template.css
    index.js
    view.js
    admin.css
    admin.js
  • 原文地址:https://www.cnblogs.com/keanuyaoo/p/3291999.html
Copyright © 2011-2022 走看看