本文共 2221 字,大约阅读时间需要 7 分钟。
userdata是lua提供给开发者自定义C/C++数据结构的一套api,他能够在C/C++层映射内存空间,使我们的程序能够更加的灵活。下面我就来介绍一下userdata是如何绑定C/C++对象的。
首先定义构造函数如下
#define HTTP_REQUEST_META_NAME "HttpRequest"class HttpRequestWrapper { public: HttpRequestWrapper(const char*bind,const char*host, int port){ } static int create(lua_State* L) { const char* bind = lua_tostring(L, 2); const char* host = lua_tostring(L, 3); int port = (int) lua_tointeger(L, 4); w = new HttpRequestWrapper(bind,host,port); if (w == NULL) goto FAIL; void **u = (void**) lua_newuserdata(L, sizeof(void*)); if (!u) goto FAIL; *u = w; luaL_getmetatable(L, HTTP__META_NAREQUESTME); lua_setmetatable(L, -2); return 1; FAIL: { printf("HttpRequest::create> failed!"); return 0; } }
之后我们要给他定义一个gc函数,好让lua虚拟机自动回收内存
static int __gc(lua_State* L) { void **s = (void**) luaL_checkudata(L, 1, HTTP__META_NAREQUESTME); if (*s == NULL) return NULL; luaL_argcheck(L, s != NULL, 1, "invalid user data"); HttpRequestWrapper ret = (HttpRequestWrapper*) (*s); if(ret != NULL){ delete ret ; *s = NULL; } return 0; }
我们再给他定义一个打印函数,验证userdata是否建立成功
static int print(lua_State *L) { void **s = (void**) luaL_checkudata(L, 1, HTTP__META_NAREQUESTME); if (*s == NULL) return NULL; luaL_argcheck(L, s != NULL, 1, "invalid user data"); HttpRequestWrapper ret = (HttpRequestWrapper*) (*s); if (ret != NULL) { printf("HttpRequest::print>...0"); const char *str = lua_tostring(L, 2); printf("HttpRequest::print> %s", str); } return 0; }
最后我们要讲自定义的userdata注册到lua虚拟机中
static const struct luaL_Reg http_request_lib_f[] = { { "create", HttpRequestWrapper::create }, { NULL, NULL } };static const struct luaL_Reg http_request_lib_m[] = { { "__gc", HttpRequestWrapper::__gc }, { "print", HttpRequestWrapper::print }, { NULL, NULL }};static int luaopen_http_request(lua_State *L) { luaL_newmetatable(L, HTTP_REQUEST_META_NAME); lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); luaL_setfuncs(L, http_request_lib_m, 0); luaL_newlib(L, http_request_lib_f); return 1;}
于是乎我们就可以在lua中使用自定义的userdata了
local bind = ‘any’local host,port = ‘127.0.0.1’,8081local h = HttpRequest:create(bind, host, port)h:print(‘aaaaaaaaaaaaaa’)
转载地址:http://vbvhz.baihongyu.com/