zoukankan      html  css  js  c++  java
  • lua的closure创建和使用

        lua的闭包包括CClosure和FClosure两种类型。下面的例子介绍如何在C中使用C创建的闭包函数,C中使用lua中创建的闭包函数,Lua中使用C中创建的闭包函数,Lua中使用Lua闭包就不赘述了。

        C中通过lua_pushclosure创建闭包函数,在将闭包函数推到堆栈之前需要先把n个上值推到lua_state上。取用的时使用lua_upvalueindex(n)取的特定索引上的上值,更改的话可以使用lua_replace更改上值。例子中每次将上值+5,因此在lua中每次调用upvalue_test函数都会获得正确的上值。lua中的closure想在C中进行upvalue的更改有一点麻烦,首先你需要获取closure函数对象,使用lua_getupvalue将特定索引上的上值放到栈顶,可以使用lua_setupvalue重设上值。如果你的fclosure中没有使用全局变量,那么其上值索引应该是按照local变量的声明顺序来的,但是一旦使用了全局变量,第一个上值必定是_ENV环境,也就是说你可以通过重新设置_ENV环境,修改全局的上值,这也是修改环境变量的一种方法。

        C 文件:

    #include <stdio.h>
    #include <string.h>
    #include <lua.h>
    #include <lauxlib.h>
    #include <lualib.h>
    #include <dlfcn.h>
    #include <math.h>
    
    static int mytest(lua_State *L) {
      //获取上值
      int upv = (int)lua_tonumber(L, lua_upvalueindex(1));
      printf("%d
    ", upv);
      upv += 5;
      lua_pushinteger(L, upv);
      lua_replace(L, lua_upvalueindex(1));
    
      //获取一般参数
      printf("%d
    ", (int)lua_tonumber(L,1));
    
      return 0;
    }
    
    int main(void) {
      lua_State *L = luaL_newstate();
      luaL_openlibs(L);
    
      //设置Cclosure函数的上值
      lua_pushinteger(L,10);
      lua_pushinteger(L,11);
      lua_pushcclosure(L,mytest,2);
      lua_setglobal(L,"upvalue_test");
      luaL_dofile(L, "./luatest.lua");
    
      //获取fclosure上值的名称(临时值, 不带env)
      lua_getglobal(L, "l_counter");
      const char *name = lua_getupvalue(L, -1, 1);
      printf("%s
    ", name);
    
      //设置fclosure上值
      lua_getglobal(L, "l_counter");
      lua_pushinteger(L,1000);
      name = lua_setupvalue(L, -2, 1);
      printf("%s
    ", name);
    
      lua_getglobal(L,"ltest");
      lua_pcall(L,0,0,0);
      lua_getglobal(L,"ltest");
      lua_pcall(L,0,0,0);
    
      //获取fclosure的上值(带env)
      lua_getglobal(L, "g_counter");
      lua_getupvalue(L, -1, 1);
      
      //通过settable重新设置env中对应的值
      lua_pushstring(L, "gloval_upvalue");
      lua_pushinteger(L,10000);
      lua_settable(L,-3);
      
      lua_pushstring(L, "gloval_upvalue1");
      lua_pushinteger(L,20000);
      lua_settable(L,-3);
      
      lua_getglobal(L,"gtest");
      lua_pcall(L,0,0,0);
      lua_close(L);
      return 0;
    }
    

      Lua 文件

         

    gloval_upvalue = 10
    gloval_upvalue1 = 20
    local local_upvalue = 100
    
    function l_counter()
       return function ()
          local_upvalue = local_upvalue + 1
          return local_upvalue
       end
    end
    
    function g_counter()
       return function ()
          gloval_upvalue = gloval_upvalue + 1
          return gloval_upvalue,gloval_upvalue1
       end
    end
    
    g_testf = g_counter()
    l_testf = l_counter()
    
    function gtest()
      print(g_testf())
    end
    
    
    function ltest()
      print(l_testf())
    end
    
    upvalue_test(1,2,3)
    upvalue_test(4,5,6)
    

      

  • 相关阅读:
    【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-7 混合概率密度
    【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-6 直接光源采样
    【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-5 random direction & ONB
    【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-4 基于重要性采样的材质初探
    【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-3 蒙特卡罗 (三)
    区域生长算法 全局分类 C++ & matlab
    智能优化 之 下山单纯形法 C++
    图形暂时停更
    【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-2 蒙特卡罗(二) 重要性采样
    【RAY TRACING THE REST OF YOUR LIFE 超详解】 光线追踪 3-1 蒙特卡罗 (一)
  • 原文地址:https://www.cnblogs.com/biyeqingfeng/p/4990101.html
Copyright © 2011-2022 走看看