亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > 綜合 > 正文

Lua教程(二十二):userdata

2024-07-21 23:04:46
字體:
來源:轉載
供稿:網友

在Lua中可以通過自定義類型的方式與C語言代碼更高效、更靈活的交互。這里我們通過一個簡單完整的示例來學習一下Lua中userdata的使用方式。需要說明的是,該示例完全來自于Programming in Lua。其功能是用C程序實現一個Lua的布爾數組,以提供程序的執行效率。見下面的代碼和關鍵性注釋。  

 

復制代碼 代碼如下:

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

 

#define BITS_PER_WORD (CHAR_BIT * sizeof(int))
#define I_WORD(i)     ((unsigned int)(i))/BITS_PER_WORD
#define I_BIT(i)      (1 << ((unsigned int)(i)%BITS_PER_WORD))

typedef struct NumArray {
    int size;
    unsigned int values[1];
} NumArray;

extern "C" int newArray(lua_State* L)
{
    //1. 檢查第一個參數是否為整型。以及該參數的值是否大于等于1.
    int n = luaL_checkint(L,1);
    luaL_argcheck(L, n >= 1, 1, "invalid size.");
    size_t nbytes = sizeof(NumArray) + I_WORD(n - 1) * sizeof(int);
    //2. 參數表示Lua為userdata分配的字節數。同時將分配后的userdata對象壓入棧中。
    NumArray* a = (NumArray*)lua_newuserdata(L,nbytes);
    a->size = n;
    for (int i = 0; i < I_WORD(n - 1); ++i)
        a->values[i] = 0;
    //獲取注冊表變量myarray,該key的值為metatable。
    luaL_getmetatable(L,"myarray");
    //將userdata的元表設置為和myarray關聯的table。同時將棧頂元素彈出。
    lua_setmetatable(L,-2);
    return 1;
}

extern "C" int setArray(lua_State* L)
{
    //1. Lua傳給該函數的第一個參數必須是userdata,該對象的元表也必須是注冊表中和myarray關聯的table。
    //否則該函數報錯并終止程序。
    NumArray* a = (NumArray*)luaL_checkudata(L,1,"myarray");
    int index = luaL_checkint(L,2) - 1;
    //2. 由于任何類型的數據都可以成為布爾值,因此這里使用any只是為了確保有3個參數。
    luaL_checkany(L,3);
    luaL_argcheck(L,a != NULL,1,"'array' expected.");
    luaL_argcheck(L,0 <= index && index < a->size,2,"index out of range.");
    if (lua_toboolean(L,3))
        a->values[I_WORD(index)] |= I_BIT(index);
    else
        a->values[I_WORD(index)] &= ~I_BIT(index);
    return 0;
}

extern "C" int getArray(lua_State* L)
{
    NumArray* a = (NumArray*)luaL_checkudata(L,1,"myarray");
    int index = luaL_checkint(L,2) - 1;
    luaL_argcheck(L, a != NULL, 1, "'array' expected.");
    luaL_argcheck(L, 0 <= index && index < a->size,2,"index out of range");
    lua_pushboolean(L,a->values[I_WORD(index)] & I_BIT(index));
    return 1;
}

extern "C" int getSize(lua_State* L)
{
    NumArray* a = (NumArray*)luaL_checkudata(L,1,"myarray");
    luaL_argcheck(L,a != NULL,1,"'array' expected.");
    lua_pushinteger(L,a->size);
    return 1;
}

extern "C" int array2string(lua_State* L)
{
    NumArray* a = (NumArray*)luaL_checkudata(L,1,"myarray");
    lua_pushfstring(L,"array(%d)",a->size);
    return 1;
}

static luaL_Reg arraylib_f [] = {
    {"new", newArray},
    {NULL, NULL}
};

static luaL_Reg arraylib_m [] = {
    {"set", setArray},
    {"get", getArray},
    {"size", getSize},
    {"__tostring", array2string}, //print(a)時Lua會調用該元方法。
    {NULL, NULL}
};

extern "C" __declspec(dllexport)
int luaopen_testuserdata(lua_State* L)
{
    //1. 創建元表,并將該元表指定給newArray函數新創建的userdata。在Lua中userdata也是以table的身份表現的。
    //這樣在調用對象函數時,可以通過驗證其metatable的名稱來確定參數userdata是否合法。
    luaL_newmetatable(L,"myarray");
    lua_pushvalue(L,-1);
    //2. 為了實現面對對象的調用方式,需要將元表的__index字段指向自身,同時再將arraylib_m數組中的函數注冊到
    //元表中,之后基于這些注冊函數的調用就可以以面向對象的形式調用了。
    //lua_setfield在執行后會將棧頂的table彈出。
    lua_setfield(L,-2,"__index");
    //將這些成員函數注冊給元表,以保證Lua在尋找方法時可以定位。NULL參數表示將用棧頂的table代替第二個參數。
    luaL_register(L,NULL,arraylib_m);
    //這里只注冊的工廠方法。
    luaL_register(L,"testuserdata",arraylib_f);
    return 1;
}


 
輕量級userdata:

 

  之前介紹的是full userdata,Lua還提供了另一種輕量級userdata(light userdata)。事實上,輕量級userdata僅僅表示的是C指針的值,即(void*)。由于它只是一個值,所以不用創建。如果需要將一個輕量級userdata放入棧中,調用lua_pushlightuserdata即可。full userdata和light userdata之間最大的區別來自于相等性判斷,對于一個full userdata,它只是與自身相等,而light userdata則表示為一個C指針,因此,它與所有表示同一指針的light userdata相等。再有就是light userdata不會受到垃圾收集器的管理,使用時就像一個普通的整型數字一樣。

 
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品毛片网大全| 亚洲一区二区三| 57pao成人永久免费视频| 色狠狠久久aa北条麻妃| 久久夜精品va视频免费观看| 中文综合在线观看| 日韩在线精品一区| 8090理伦午夜在线电影| 亚洲一区美女视频在线观看免费| 精品视频久久久久久久| 欧美精品午夜视频| 成人国产精品久久久久久亚洲| 亚洲美女av网站| 在线观看视频99| 亚洲男人天堂手机在线| 国产欧美精品va在线观看| 欧美黑人一级爽快片淫片高清| www.日本久久久久com.| 91高清在线免费观看| 欧美最猛性xxxxx免费| 成人黄色中文字幕| 91理论片午午论夜理片久久| 国产成人一区二区三区| 亚洲一区二区三区在线视频| 91久久精品美女| 国产激情视频一区| 97色在线观看| 亚洲欧洲第一视频| 精品久久久久国产| 成人免费xxxxx在线观看| 91免费精品视频| 欧美激情一二三| 欧美电影院免费观看| 国产不卡一区二区在线播放| 欧美日韩亚洲视频一区| 一区二区国产精品视频| 亚洲wwwav| 久久99久久99精品中文字幕| 久久久久久久网站| 欧美第一淫aaasss性| 两个人的视频www国产精品| 日本最新高清不卡中文字幕| 欧亚精品中文字幕| 夜色77av精品影院| 亚洲xxx视频| 国产精品激情av在线播放| 国产综合视频在线观看| 欧美精品videossex性护士| 亚洲毛片在线免费观看| 国产精品香蕉在线观看| 亚洲免费精彩视频| 亚洲sss综合天堂久久| 欧美在线视频免费| 欧美精品福利在线| 中文字幕精品视频| 色婷婷综合久久久久中文字幕1| 亚洲韩国日本中文字幕| 欧日韩在线观看| 精品欧美国产一区二区三区| 成人黄色在线免费| 亚洲品质视频自拍网| 中文字幕日韩在线视频| 成人国产在线激情| 国产精品自拍视频| 日韩高清电影好看的电视剧电影| 欧美精品免费播放| 97福利一区二区| 国产精品久久久久久久天堂| 伊人青青综合网站| 亚洲成人精品在线| 日韩精品电影网| 国产小视频91| 国产精品极品尤物在线观看| 日本午夜在线亚洲.国产| 色狠狠av一区二区三区香蕉蜜桃| 91av福利视频| 精品美女久久久久久免费| 日韩激情av在线播放| 久久久噜噜噜久久久| 中文.日本.精品| 日本不卡高字幕在线2019| 欧美日韩国产123| 中文字幕在线日韩| 国产精品欧美亚洲777777| 欧美激情2020午夜免费观看| 日本精品视频在线观看| 精品亚洲一区二区三区四区五区| 国产欧美一区二区三区在线| 国产精品久久久久久一区二区| 久久久久久久久久久国产| 日韩av在线播放资源| 成人黄色激情网| 91av视频导航| 久久夜色精品国产| 亚洲一级一级97网| 国产福利成人在线| 日韩激情片免费| 久久色精品视频| 成人乱色短篇合集| 国产成人精品a视频一区www| 九九精品在线观看| 亚洲三级黄色在线观看| 欧美人与物videos| 午夜精品美女自拍福到在线| 国产激情999| 欧美乱大交做爰xxxⅹ性3| 日韩在线观看电影| …久久精品99久久香蕉国产| 狠狠色狠狠色综合日日五| 日韩中文综合网| 97香蕉超级碰碰久久免费的优势| 国内精品久久久久影院优| 亚洲精品一二区| 欧美激情网站在线观看| 中文字幕亚洲欧美日韩高清| 亚洲精品久久久久久久久久久久久| 精品中文视频在线| 自拍视频国产精品| 成人写真视频福利网| 日韩黄在线观看| 日韩在线视频播放| 国产日韩精品电影| 亚洲精品美女视频| 久久久国产精品一区| 日日狠狠久久偷偷四色综合免费| 国产精品青草久久久久福利99| 国产一区二区三区视频在线观看| 中文字幕亚洲色图| 91久久夜色精品国产网站| 欧美日韩中文在线观看| 尤物精品国产第一福利三区| 久久夜色精品国产亚洲aⅴ| 中文字幕精品网| 日韩精品中文在线观看| 自拍亚洲一区欧美另类| 国产亚洲欧美日韩美女| 久久亚洲综合国产精品99麻豆精品福利| 国产精品永久免费在线| 美女福利精品视频| 亚洲三级黄色在线观看| 亚洲黄在线观看| 久久综合久久美利坚合众国| 久久精品欧美视频| 日韩精品小视频| 亚洲伊人成综合成人网| 欧美插天视频在线播放| 欧美亚洲在线视频| 亚洲区中文字幕| 国模gogo一区二区大胆私拍| 国产91网红主播在线观看| 国产美女直播视频一区| 日本精品视频在线| 91中文字幕在线| 日韩天堂在线视频| 国产精品视频公开费视频| 91精品国产综合久久久久久蜜臀| 久久久久免费精品国产| 中文字幕视频在线免费欧美日韩综合在线看| 国产精品日韩在线| 亚洲视频999| 欧美综合在线观看| 国产日本欧美在线观看| 最近2019年中文视频免费在线观看| 97色在线观看|