Lua自定义userdata(与C++对象绑定)

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,8081
local h = HttpRequest:create(bind, host, port)
h:print(‘aaaaaaaaaaaaaa’)
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页