.h
#ifndef _lua_cus_data_type_
#define _lua_cus_data_type_
#include <limits.h>
extern "C"
{
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
}
#define BITS_PER_WORD (CHAR_BIT*sizeof(unsigned int))
#define I_WORD(i) ((unsigned int)(i) / BITS_PER_WORD)
#define I_BIT(i) (1<< ((unsigned int) (i)% BITS_PER_WORD))
#define checkarray(L) \
(NumArray*)luaL_checkudata(L,1,"LuaBook.array")
typedef struct NumArray
{
int size;
unsigned int values[1];
} NumArray;
extern "C"
{
int luaopen_array(lua_State*L);
}
#endif
.cc
#include "luaCusDataType.h"
static int newarray(lua_State *L)
{
int i, n;
size_t nbytes;
NumArray *a;
n = luaL_checkint(L, 1);
luaL_argcheck(L, n >= 1, 1, "invalid size");
nbytes = sizeof(NumArray) + I_WORD(n - 1) *sizeof(unsigned int);
a = (NumArray*)lua_newuserdata(L, nbytes);
a->size = n;
for (i = 0; i < I_WORD(n - 1); i++)
{
a->values[i] = 0;
}
luaL_getmetatable(L, "LuaBook.array");
lua_setmetatable(L, -2);
return 1; // 新的userdata 已经在栈上
}
static int setarray(lua_State*L)
{
//NumArray* a = (NumArray*)lua_touserdata(L, 1);
NumArray*a = checkarray(L);
int index = luaL_checkint(L, 2) - 1;
luaL_checkany(L, 3);
luaL_argcheck(L, a != NULL, 1, "'array' excepted");
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;
}
static int getarray(lua_State*L)
{
//NumArray*a = (NumArray*)lua_touserdata(L, 1);
NumArray*a = checkarray(L);
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;
}
static int getsize(lua_State*L)
{
//NumArray*a = (NumArray*)lua_touserdata(L, 1);
NumArray*a = checkarray(L);
luaL_argcheck(L, "a != NULL", 1, "'array' expected !");
lua_pushinteger(L, a->size);
return 1;
}
static const struct luaL_Reg arrayLib[] =
{
{ "new", newarray},
{ "set", setarray},
{ "get", getarray},
{ "size", getsize},
{ NULL,NULL}
};
static const struct luaL_Reg arraylib_f[] =
{
{"new",newarray},
{NULL,NULL},
};
static const struct luaL_Reg arraylib_m[] =
{
{ "set", setarray },
{ "get", getarray },
{ "size", getsize },
{ NULL, NULL },
};
extern "C"
{
/*
int luaopen_array(lua_State*L)
{
fprintf(stderr, "******************************\n");
fprintf(stderr, "************** luaopen_array ****************\n");
fprintf(stderr, "******************************\n");
luaL_newmetatable(L, "LuaBook.array");
luaL_register(L, "array", arrayLib);
return 1;
}
*/
int luaopen_array(lua_State*L)
{
int a = lua_gettop(L);
luaL_newmetatable(L, "LuaBook.array");
int b = lua_gettop(L);
lua_pushvalue(L, -1); // 复制元表
int c = lua_gettop(L);
lua_setfield(L, -2, "__index");
int d = lua_gettop(L);
luaL_register(L, NULL, arraylib_m);
int m = lua_gettop(L);
luaL_register(L,"array",arraylib_f);
int n = lua_gettop(L);
fprintf(stderr, "a ,b,c,d,m,n = %d,%d,%d,%d,%d,%d\n",a,b,c,d,m,n);
return 1;
}
}