void *lua_newuserdata (lua_State *L, size_t size);
lua_newuserdata 函数按照指定的大小分配一块内存,将对应的 userdatum放到栈内,
并返回内存块的地址。
一个简单的调用lua_newuserdata 分配空间的例子:
LuaTestDll.h
extern "C"
{
#include "lua/lua.h"
#include "lua/lualib.h"
#include "lua/lauxlib.h"
#include "lua/luaconf.h"
LUATESTDLL_API int luaopen_mylib(lua_State *L);
};
LuaTestDll.cpp
#include "LuaTestDll.h"
typedef struct NumArray
{
int size;
double values[1];
}NumArray;
static int newarray(lua_State *L)
{
int n = luaL_checkint(L,1);
//由于原始的结构中已经包含了一个元素的空间,所以我们从n 中减去 1
size_t nbytes = sizeof(NumArray) + (n-1)*sizeof(double);
//调用lua_newuserdata分配指定的大小空间,并压入栈中作为返回值
NumArray *a = (NumArray*)lua_newuserdata(L,nbytes);
a->size = n;
//分配的内存已经在栈中
return 1;
}
static int setarray(lua_State *L)
{
NumArray *a = (NumArray*)lua_touserdata(L,1);
int index = luaL_checkint(L,2);
double value = luaL_checknumber(L,3);
luaL_argcheck(L,a != NULL,1,"array expected");
luaL_argcheck(L,1<=index && index <=a->size,2,"index out of range");
//设置数组值
a->values[index-1] = value;
return 0;
}
static int getarray (lua_State *L)
{
NumArray *a = (NumArray*)lua_touserdata(L,1);
int index = luaL_checkint(L,2);
luaL_argcheck(L,a != NULL,1,"array expected");
luaL_argcheck(L,1<=index && index <=a->size,2,"index out of range");
//返回对应值
lua_pushnumber(L,a->values[index-1]);
return 1;
}
static int getsize(lua_State *L)
{
NumArray *a = (NumArray*)lua_touserdata(L,1);
//判断参数正确性
luaL_argcheck(L,a != NULL,1,"array expected");
//返回数组大小
lua_pushnumber(L,a->size);
return 1;
}
static const struct luaL_reg arraylib[] =
{
{"new",newarray},
{"set",setarray},
{"get",getarray},
{"size",getsize},
{NULL,NULL}
};
int luaopen_mylib(lua_State *L)
{
luaL_openlib(L,"array",arraylib,0);
return 1;
}
Test.lua
func = package.loadlib("LuaTestDll.dll","luaopen_mylib");
func(); --导出函数
a = array.new(1000); --分配1000个空间大小
print(a); --> userdata: 0x8064d48
print(array.size(a)); --> 1000
for i=1,1000 do
array.set(a,i,1/i);
end
print(array.get(a,10)); --> 0.1