是很很巧妙的方法。之所以巧妙,是因为上面的操作,几乎所有的代码,都可以用程序来生成。只需要扫描和分析头文件。
lua++大概就是这么做的吧。
尝试了一晚上,差不多做成了一个demo,只是getter没有在c里写,直接在lua里写的。这样肯定是不妥的,但为了加快速度,只好...
下面是主要的代码:
点击(此处)折叠或打开
-
wrapper.c
-
#include<stdio.h>
-
#include<lua.h>
-
#include<lualib.h>
-
#include<dog.h>
-
-
-
-
/*lua 似乎是这样,每次调用一个fucntion时,会清除栈上的参数和function*/
-
int getAttr(lua_State *L){
-
char *key = lua_tostring(L, -1);
-
-
lua_getmetatable(L, -2);
-
lua_pushstring(L, "get");
-
lua_gettable(L, -2); /**stack top:table= mtbl.get*/
-
lua_pushstring(L, key);
-
lua_gettable(L, -2); /**stack top:function = get.key*/
-
int err = lua_pcall(L, 0, 1, 0); /**核心在这里... ,暂时简化,规定get表的一堆getter都只返回1个integer*/
-
int getval;
-
if(err != 0){
-
//调用失败的话,lua_pcall会push一个error code。很好。
-
printf("can not find corresponding getter\n");
-
getval = -1;
-
}
-
else{
-
getval = lua_tointeger(L, -1);
-
-
}
-
lua_pop(L, 3);
-
lua_pushinteger(L, getval);
-
return 1;
-
}
-
/*prototype: userdata createDog(void)*/
-
int createDog(lua_State *L){
-
struct dog *dog = lua_newuserdata(L, sizeof(struct dog));
-
-
luaL_newmetatable(L, "mtbl");
-
lua_pushstring(L, "__index");
-
lua_pushcfunction(L, getAttr);/**你搞清楚,这里已经是把c函数注册到lua的一个key里了,不用再lua_register()*/
-
lua_settable(L, -3);
-
-
lua_pushstring(L, "get");
-
lua_newtable(L);
-
lua_settable(L, -3);
-
-
lua_setmetatable(L, -2);
-
-
return 1;
-
}
-
-
int luaopen_cmodule(lua_State *L){
-
lua_register(L, "createDog", createDog);
-
return 0;
- }
点击(此处)折叠或打开
- Lua 5.1.4 Copyright (C) 1994-2008 Lua.org, PUC-Rio
- > require"cmodule"
- > d=createDog()
- > mtbl=getmetatable(d)
- > mtbl.get.age = function() return 1234 end
- > print(d.agee)
- can not find corresponding getter
- -1
- > print(d.age)
- 1234
- >