lua userdata metatable

.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;
	}
}

 

转载于:https://my.oschina.net/lyr/blog/1552132

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值