zoukankan      html  css  js  c++  java
  • lua sample code analysis

    What is a meta table

    a meta table has a __name attr whose value is name of metatable
    a meta table is stored in LUA_REGISTRYINDEX whose key is its name
    

    Code analysis

    Appl

    DUMP_STACK(L);
    /*{ "foo", "C:\jshe\codes\mylualib\test\../build/v100+x64+Debug/foo_vc100_64.
    dll" }*/	
    	//1. 创建元表,并将该元表指定给newArray函数新创建的userdata。在Lua中userdata也是以table的身份表现的。
    	//这样在调用对象函数时,可以通过验证其metatable的名称来确定参数userdata是否合法。
    	luaL_newmetatable(L,"myarray");
    	lua_pushvalue(L,-1);
    
    	/*
    top=4
    4/-1: type=table{__name='myarray', }
    3/-2: type=table{__name='myarray', }	-->name it mt
    2/-3: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-4: type=string'foo'
    
    	*/
    	
    	//2. 为了实现面对对象的调用方式,需要将元表的__index字段指向自身,同时再将arraylib_m数组中的函数注册到
    	//元表中,之后基于这些注册函数的调用就可以以面向对象的形式调用了。
    	//lua_setfield在执行后会将栈顶的table弹出。
    	lua_setfield(L, -2, "__index");	// mt.__index = mt
    
    	/*
    top=3
    3/-1: type=table{__index={__index={__index={__index={__index=, __name=, }, __name='myarray', }, __name='myarray', }, __name='myarray', }, __name='myarray', }
    2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-3: type=string'foo'*/
    	
    	//将这些成员函数注册给元表,以保证Lua在寻找方法时可以定位。NULL参数表示将用栈顶的table代替第二个参数。
    	luaL_register(L, NULL, arraylib_m);
    
    	//这里只注册的工厂方法。
    	luaL_register(L,"testuserdata",arraylib_f);
    
    	DUMP_STACK(L);
    /*{ "foo", "C:\jshe\codes\mylualib\test\../build/v100+x64+Debug/foo_vc100_64.
    dll", <1>{
        __gc = <function 1>,
        __index = <table 1>,
        __name = "myarray",
        __tostring = <function 2>,
        get = <function 3>,
        set = <function 4>,
        size = <function 5>
      }, {
        new = <function 6>
      } }
    */
    	luaL_register(L,"testuserdatafm",arraylib_f_and_m);
    
    	DUMP_STACK(L);
    /*{ "foo", "C:\jshe\codes\mylualib\test\../build/v100+x64+Debug/foo_vc100_64.
    dll", <1>{
        __gc = <function 1>,
        __index = <table 1>,
        __name = "myarray",
        __tostring = <function 2>,
        get = <function 3>,
        set = <function 4>,
        size = <function 5>
      }, {
        new = <function 6>
      }, {
        get = <function 3>,
        new = <function 6>,
        set = <function 4>,
        size = <function 5>,
        tostring = <function 2>
      } }*/
    	luaopen_packet(L);
    /*{ "foo", "C:\jshe\codes\mylualib\test\../build/v100+x64+Debug/foo_vc100_64.
    dll", <1>{
        __gc = <function 1>,
        __index = <table 1>,
        __name = "myarray",
        __tostring = <function 2>,
        get = <function 3>,
        set = <function 4>,
        size = <function 5>
      }, {
        new = <function 6>
      }, {
        get = <function 3>,
        new = <function 6>,
        set = <function 4>,
        size = <function 5>,
        tostring = <function 2>
      }, {
        creatPacket = <function 7>
      } }
    */
    	
    	=========
    

    luaL_newmetatable

    LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) {
      if (luaL_getmetatable(L, tname) != LUA_TNIL)  /* name already in use? */	// top=1
        return 0;  /* leave previous value on top, but return 0 */
    	/*top=3
    3/-1: type=nil
    2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-3: type=string'foo'
    */
      lua_pop(L, 1);	// =0
      lua_createtable(L, 0, 2);  /* create metatable */ // =1
    /*top=3
    3/-1: type=table{}
    2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-3: type=string'foo'*/  
      lua_pushstring(L, tname);	// =2
     /*top=4
    4/-1: type=string'myarray'
    3/-2: type=table{}
    2/-3: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-4: type=string'foo'*/ 
      lua_setfield(L, -2, "__name");  /* metatable.__name = tname */	// =1
      /*top=3
    3/-1: type=table{'myarray', }
    2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-3: type=string'foo'*/
      lua_pushvalue(L, -1);	// =2
        /*top=4
    4/-1: type=table{__name='myarray', }
    3/-2: type=table{__name='myarray', }
    2/-3: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-4: type=string'foo'*/
      lua_setfield(L, LUA_REGISTRYINDEX, tname);  /* registry.name = metatable */
    /*top=3
    3/-1: type=table{__name='myarray', }
    2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-3: type=string'foo'*/  
      return 1;
    }
    	
    

    EnumTableItem

    void EnumTableItem(lua_State *L, int index, int nDepth)
    {
    /*top=4
    4/-1: type=table{C:000007FEEF9610EB, }
    3/-2: type=table{'myarray', {, , , , , , , }, C:000007FEEF961131, C:000007FEEF9611A9, C:000007FEEF961163, C:000007FEEF961113, C:000007FEEF96103C, }
    2/-3: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-4: type=string'foo'
    */
    	int top = lua_gettop(L);
    
    	lua_pushvalue(L, index);	// copy the variable to stack top // +1
    	int it = lua_gettop(L);
    	myprintf("{");
    	lua_pushnil(L);	
    	/*{----------8, NA, 0
    top=6
    6/-1: type=nil
    5/-2: type=table{C:000007FEEF9610EB, }
    4/-3: type=table{C:000007FEEF9610EB, }
    3/-4: type=table{'myarray', {, , , , , , , }, C:000007FEEF961131, C:000007FEEF9611A9, C:000007FEEF961163, C:000007FEEF961113, C:000007FEEF96103C, }
    2/-5: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-6: type=string'foo'
    */
    	// 2
    	while (lua_next(L, it))			// If there is data, then top++, else top--	
    	{
    /*top=7
    7/-1: type=functionC:000007FEEF9610EB
    6/-2: type=string'new'
    5/-3: type=table{C:000007FEEF9610EB, }
    4/-4: type=table{C:000007FEEF9610EB, }
    3/-5: type=table{'myarray', {, , , , , , , }, C:000007FEEF961131, C:000007FEEF9611A9, C:000007FEEF961163, C:000007FEEF961113, C:000007FEEF96103C, }
    2/-6: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-7: type=string'foo'
    */	
    		DumpItemEx(L, -1, nDepth+1);
    		myprintf(", ");
    		lua_pop(L, 1);
    	}						// 1
    	myprintf("}");
    	lua_pop(L, 1);			// 0
    	int top2 = lua_gettop(L);
    	assert(top==top2);
    }
    	
    #define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0))
    

    luaL_openlib

    LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
                                   const luaL_Reg *l, int nup) {
    /*top=3
    3/-1: type=table{__index={__index={__index={__index={__index=, __name=, }, __name='myarray', }, __name='myarray', }, __name='myarray', }, __name='myarray', }
    2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-3: type=string'foo'
    */							   
      luaL_checkversion(L);
      if (libname) {
        luaL_pushmodule(L, libname, libsize(l));  /* get/create library table */
        lua_insert(L, -(nup + 1));  /* move library table to below upvalues */
      }
      if (l)
        luaL_setfuncs(L, l, nup);
      else
        lua_pop(L, nup);  /* remove upvalues */
    }
    

    luaL_setfuncs

    // This function fills the functions to a table
    // the key function is
    // lua_pushcclosure, lua_setfield
    //
    LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
    /*top=3
    3/-1: type=table{__index={__index={__index={__index={__index=, __name=, }, __name='myarray', }, __name='myarray', }, __name='myarray', }, __name='myarray', }
    2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-3: type=string'foo'
    */
      luaL_checkstack(L, nup, "too many upvalues");
      for (; l->name != NULL; l++) {  /* fill the table with given functions */
        int i;
        for (i = 0; i < nup; i++)  /* copy upvalues to the top */
          lua_pushvalue(L, -nup);
        lua_pushcclosure(L, l->func, nup);  /* closure with those upvalues */
    /*top=4
    4/-1: type=functionC:000007FED9A21131
    3/-2: type=table{__index={__index={__index={__index={__index=, __name=, }, __name='myarray', }, __name='myarray', }, __name='myarray', }, __name='myarray', }
    2/-3: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-4: type=string'foo'
    */	
        lua_setfield(L, -(nup + 2), l->name);
    /*top=3
    3/-1: type=table{__index={__index={__index={__index={__index=, __name=, set=, }, __name='myarray', set=C:000007FED9A21131, }, __name='myarray', set=C:000007FED9A21131, }, __name='myarray', set=C:000007FED9A21131, }, __name='myarray', set=C:000007FED9A21131, }
    2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-3: type=string'foo'
    */	
      }
      lua_pop(L, nup);  /* remove upvalues */
      
    /*top=3
    3/-1: type=table{__index={__index={__index={__index={__index=, set=, __gc=, __tostring=, get=, size=, __name=, }, set=C:000007FED9A21131, __gc=C:000007FED9A21163, __tostring=C:000007FED9A211A9, get=C:000007FED9A2103C, size=C:000007FED9A21113, __name='myarray', }, set=C:000007FED9A21131, __gc=C:000007FED9A21163, __tostring=C:000007FED9A211A9, get=C:000007FED9A2103C, size=C:000007FED9A21113, __name='myarray', }, set=C:000007FED9A21131, __gc=C:000007FED9A21163, __tostring=C:000007FED9A211A9, get=C:000007FED9A2103C, size=C:000007FED9A21113, __name='myarray', }, set=C:000007FED9A21131, __gc=C:000007FED9A21163, __tostring=C:000007FED9A211A9, get=C:000007FED9A2103C, size=C:000007FED9A21113, __name='myarray', }
    2/-2: type=string'C:jshecodesmylualib	est../build/v100+x64+Debug/foo_vc100_64.dll'
    1/-3: type=string'foo'
    */  
    }
    
  • 相关阅读:
    不常用的cmd命令
    js获取宽度
    Marshaling Data with Platform Invoke 概览
    Calling a DLL Function 之三 How to: Implement Callback Functions
    Marshaling Data with Platform Invoke 之四 Marshaling Arrays of Types
    Marshaling Data with Platform Invoke 之一 Platform Invoke Data Types
    Marshaling Data with Platform Invoke 之三 Marshaling Classes, Structures, and Unions(用时查阅)
    Calling a DLL Function 之二 Callback Functions
    WCF 引论
    Marshaling Data with Platform Invoke 之二 Marshaling Strings (用时查阅)
  • 原文地址:https://www.cnblogs.com/cutepig/p/12268898.html
Copyright © 2011-2022 走看看