Chinaunix首页 | 论坛 | 博客
  • 博客访问: 56435
  • 博文数量: 13
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 130
  • 用 户 组: 普通用户
  • 注册时间: 2015-04-26 15:04
文章分类

全部博文(13)

文章存档

2015年(13)

我的朋友

分类: Android平台

2015-06-23 16:54:22

tolua++的代码看起来还是很舒服的(似乎看过linux源码之后,觉得别的代码都很亲近),模仿它写了一段时间,基本的框架出来了,这也是我想要的。先存个档吧。目前的demo是编译成dll用。、
mklua.h

点击(此处)折叠或打开

  1. #include"mklua.h"
  2. #include"mklua_event.h"

  3. /*
  4.  * 有个疑问,不是变成dll让lua用,而是从c++里开启lua,这里的lua_push用的
  5.  * 是哪里的vstack?
  6.  * BUG:这里注册到全局表的Dog找不到
  7.  */
  8. void begin_class_tbl(lua_State *L, char *class_name){
  9.     luaL_newmetatable(L, class_name);    /*stack: mt*/        
  10.     lua_newtable(L);    /*stack: mt tbl */
  11.     lua_setfield(L, -2, "getter");    /*stack: mt*/
  12.     lua_newtable(L);    /*stack: mt tbl*/
  13.     lua_setfield(L, -2, "setter");    /*stack: mt*/
  14.     lua_newtable(L);    /*stack: mt ubox*/
  15.     lua_setfield(L, -2, "ubox");    /*stack: mt */
  16. }

  17. /*
  18.  * stack: mt
  19.  */
  20. void end_class_tbl(lua_State *L){
  21.     lua_pushstring(L, "__index");
  22.     lua_pushcfunction(L, on_index);
  23.     lua_rawset(L, -3);
  24.     lua_pushstring(L, "__newindex");
  25.     lua_pushcfunction(L, on_newindex);
  26.     lua_rawset(L, -3);
  27. }

  28. /*1, 像这种lua调用的c再调用的函数,应该是沿用母栈,没有自己的vstack,
  29.  * 以,它在vstack上不能留痕迹。
  30.  *2, stack: mt
  31.  */
  32. void mklua_member(lua_State *L, char *member, lua_CFunction get_it, lua_CFunction set_it){
  33.     int ebp = lua_gettop(L);

  34.     lua_getfield(L, -1, "getter");        /*stack: mt getter */
  35.     lua_pushcfunction(L, get_it);        /*stack: mt getter get_it */
  36.     lua_setfield(L, -2, member);        /*stack: mt getter */
  37.     
  38.     lua_getfield(L, -2, "setter");        /*stack: mt getter setter */
  39.     lua_pushcfunction(L, set_it);        /*stack:mt gttr sttr set_it */
  40.     lua_setfield(L, -2, member);        /*stack: mt gttr sttr */
  41.     
  42.     lua_settop(L, ebp);
  43. }

  44. /*
  45.  * 0,直接把func挂到metatable上
  46.  * 1,stack: mt
  47.  */
  48. void mklua_function(lua_State *L, char *name, lua_CFunction func){
  49.     lua_pushcfunction(L, func);
  50.     lua_setfield(L, -2, name);
  51. }


  52. /*push ubox.lightu, 也就是以c实例为key,在ubox里找到(找不到就new一个
  53.  * )对应的userdata,并push到栈里*/
  54. void mklua_pushusertype(lua_State *L, void *cobj, const char *class_name){
  55.     luaL_getmetatable(L, class_name);    /*stack: mt */
  56.     if(lua_isnil(L, -1)){
  57.         printf("can not find class in registry\n");
  58.         return;
  59.     }
  60.     lua_getfield(L, -1, "ubox");    /*stack: mt ubox*/
  61.     if(lua_isnil(L, -1)){
  62.         printf("can not find ubox in mt\n");
  63.         return;
  64.     }
  65.     lua_pushlightuserdata(L, cobj);    /*stack: mt ubox lu */
  66.     lua_rawget(L, -2);    /*stack: mt ubox ubox.lu*/
  67.     if(lua_isnil(L, -1)){
  68.         printf("ubox.u not found, create a userdata and map it\n");
  69.         lua_pop(L, 1);
  70.         lua_pushlightuserdata(L, cobj);    /*stack:mt ubox u */
  71.         lua_newuserdata(L, sizeof(void *));    /*stack: mt ubox u ud*/

  72.         /*下面这两句,只是为了把newud保存到栈底,不然rawset就没有了*/
  73.         lua_pushvalue(L, -1);    /*stack: mt ubox u ud ud*/
  74.         lua_insert(L, -5);    /*stack: ud mt ubox u ud */

  75.         lua_rawset(L, -3);        /*stack: ud mt ubox*/
  76.         lua_pop(L, 1);        /*stack: ud mt*/
  77.         lua_setmetatable(L, -2);    /*stack: ud*/
  78.         return;
  79.     }
  80.     /*底下这一段跟上面的有重复代码,TODO*/
  81.     else lua_insert(L, -3);    /*stack: ubox.lu mt ubox */
  82.     lua_pop(L, 1);
  83.     lua_setmetatable(L, -2);    /*stack: newud */
  84.     return;    
  85. }

mklua_event.h

点击(此处)折叠或打开

  1. /*
  2.  * 1,set是一个固有的表,似乎。所以改成setter.没有,是旧的代码在后面。
  3.  * 2,现在ON_index和on_newindex的一些地方,没考虑会递归触发。要多用raw.
  4.  */
  5. #include<lua.h>
  6. #include<lualib.h>
  7. #include<lauxlib.h>
  8. #include"utils.h"

  9. int on_call(lua_State *L){

  10. }
  11. /*stack: obj key*/
  12. int on_index(lua_State *L){
  13.     int obj_type = lua_type(L, 1);

  14.     if(obj_type == LUA_TUSERDATA){

  15.         /*尝试直接从metatable上获取该属性*/
  16.         lua_getmetatable(L, -2);    /*stack: obj key mt*/    
  17.         stk_rawget(L, -1, -2);        /*stack: obj key mt mt.key*/
  18.         if(!lua_isnil(L, -1)){
  19.             return 1;
  20.         }    

  21.         /*直接从mt上获取属性失败,尝试从get表里拿getter*/
  22.         else lua_pop(L, 1);        /* stack: obj key mt */
  23.         lua_getfield(L, -1, "getter");    /*stack: obj key mt get */
  24.         stk_rawget(L, -1, 2);    /*stack: obj key mt get get.key */
  25.         /*如果是getter, 直接调用*/
  26.         if(lua_isfunction(L, -1)){
  27.             lua_pushvalue(L, 1);
  28.             lua_pushvalue(L, 2);
  29.             lua_call(L, 2, 1);
  30.             return 1;
  31.         }
  32.         else{
  33.             printf("not a getter\n");
  34.             return 1;
  35.         }
  36.     }
  37. }

  38. /*stack: obj key vlaue*/
  39. int on_newindex(lua_State *L){
  40.     const char *key = lua_tostring(L,2);
  41.     int value = lua_tointeger(L, 3);
  42.     printf("key:%s,value:%d\n", key, value);
  43.     lua_getmetatable(L, 1);    /*stack: obj key value mt */

  44.     /*先看有没有对应的setter*/    /*BUG:尽量用rawget*/
  45.     lua_getfield(L, -1, "setter");    /*stack: obj key value mt set*/
  46.     lua_pushvalue(L, 2);        /*stack: obj key value mt set key */
  47.     lua_rawget(L, -2);            /*stack: obj key value mt set set.key*/        if(lua_isfunction(L, -1)){
  48.         lua_pushvalue(L, 1);
  49.         lua_pushvalue(L, 3);
  50.         lua_call(L, 2, 0);
  51.         return 0;
  52.     }

  53.     /*找不到对应的setter,直接把这个key挂到metatable里 */
  54.     else lua_pop(L, 2);            
  55.     lua_pushvalue(L, 2);
  56.     lua_pushvalue(L, 3);
  57.     lua_rawset(L, -3);
  58.     return 0;

  59.     lua_pushvalue(L, -3);        /*stack: obj key value mt key */
  60.     lua_pushvalue(L, -3);        /*stack: obj key value mt key value*/
  61.     lua_rawset(L, -3);            /*stack: obj key value mt */

  62.     lua_settop(L, 3);
  63.     return 0;
  64. }
utils.c

点击(此处)折叠或打开

  1. #include<lua.h>
  2. #include<lualib.h>
  3. #include<lauxlib.h>
  4. #include "utils.h"

  5. void stk_rawget(lua_State

  6. *L, int tbl_index, int key_index){
  7.     lua_pushvalue(L, key_index);
  8.     if(tbl_index < 0)

  9. tbl_index--;
  10.     lua_rawget(L, tbl_index);
  11. }
dog.c

点击(此处)折叠或打开

  1. #include"dog.h"
  2. #include<lauxlib.h>
  3. #include<lualib.h>
  4. #include<stdlib.h>
  5. int _dog_say(struct Dog *dog, char *msg){
  6.     printf("voice from dog: %s\n", msg);
  7.     return 123;
  8. }

  9. struct Dog * dog_new(int age){
  10.     struct Dog* d= malloc(sizeof(struct Dog));
  11.     d->age = age;
  12.     return d;
  13. }

dog.h

点击(此处)折叠或打开

  1. #include<lauxlib.h>
  2. #include<lualib.h>
  3. struct Dog{
  4.     int age;
  5. };
  6. typedef struct Dog Dog;
  7. int _dog_say(struct Dog *, char * msg);
  8. struct Dog * dog_new(int age)
wrapper.c

点击(此处)折叠或打开

  1. /*
  2.  * 1,lua_call一个函数,会为它开启一个新stack,由母栈向子栈复制参数,
  3.  * 由子栈向母栈复制返回值。it ought be as this.
  4.  */
  5. #include<stdio.h>
  6. #include<lua.h>
  7. #include<lualib.h>
  8. #include"dog.h"
  9. #include "mklua_event.h"
  10. #include"mklua.h"
  11. int first_time = 1;

  12. /*stack age */
  13. int dog_new000(lua_State *L){
  14.     int age = lua_tointeger(L, 1);
  15.     struct Dog * dog = dog_new(100);
  16.     mklua_pushusertype(L, dog, "Dog");
  17.     return 1;
  18. }

  19. /*stack: obj value*/
  20. int dog_set_age(lua_State *L){
  21.     struct Dog *d = lua_touserdata(L, 1);

  22.     d->age = lua_tointeger(L, 2);
  23.     return 0;
  24. }

  25. /*1, auto generated by karma
  26.  *3, >>> | table | key |
  27.  */
  28. int dog_get_age(lua_State *L){
  29.     struct Dog *d = lua_touserdata(L, -2);
  30.     printf("dog addr:%x,d->age:%d\n", d,d->age);
  31.     lua_pushinteger(L, d->age);
  32.     return 1;
  33. }



  34. int mklua_open_Dog(lua_State *L){
  35.     int ebp = lua_gettop(L);
  36.     begin_class_tbl(L, "Dog");
  37.     mklua_member(L, "age", dog_get_age, dog_set_age);
  38.     mklua_function(L, "new", dog_new000);
  39.     end_class_tbl(L);
  40.     lua_settop(L, ebp);

  41.     luaL_getmetatable(L, "Dog");    
  42.     return 1;
  43. }


  44. /*prototype: userdata create(char * class_name)*/
  45. int create(lua_State *L){
  46.     if(first_time){
  47.         first_time = 0;
  48.         mklua_open_Dog(L);
  49.     }
  50.     if(!lua_isstring(L, -1)) {
  51.         printf("not a valid string\n");
  52.         return 1;
  53.     }
  54.     const char *class_name = lua_tostring(L, -1);
  55.     struct Dog *dog = lua_newuserdata(L, sizeof(struct Dog));
  56.     luaL_getmetatable(L, class_name);
  57.     if(lua_isnil(L, -1)){
  58.         printf("can not find class:%s\n", class_name);
  59.         return 1;
  60.     }
  61.     else lua_setmetatable(L, -2);
  62.     dog->age = 10;
  63.     return 1;
  64. }

  65. int luaopen_dog(lua_State *L){
  66.     lua_register(L, "opendog", mklua_open_Dog);
  67.     return 0;
  68. }





阅读(1766) | 评论(0) | 转发(0) |
0

上一篇:cygwin的点滴 0.5

下一篇:没有了

给主人留下些什么吧!~~