Lua绑定C++类

原文:http://blog.csdn.net/chenee543216/article/details/12074771

 

 

以下是代码:

Animal.h文件

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. #pragma once  
  2. #ifndef __ANIMAL_H__  
  3. #define __ANIMAL_H__  
  4.   
  5. class Animal  
  6. {  
  7. public:  
  8.     Animal( const char *name );  
  9.     void setAge( int age );  
  10.     int getAge();  
  11.     void sound();  
  12.     ~Animal(void);  
  13.   
  14. private:  
  15.     const char *name;  
  16.     int age;  
  17. };  
  18.   
  19. #endif  


Animal.cpp文件

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. #include "stdafx.h"  
  2. #include "Animal.h"  
  3.   
  4. Animal::Animal( const char* name ):age(0)  
  5. {  
  6.     this->name = name;  
  7. }  
  8.   
  9. Animal::~Animal(void)  
  10. {  
  11.     printf( "Animal destructor." );  
  12. }  
  13.   
  14. void Animal::setAge( int age )  
  15. {  
  16.     this->age = age;  
  17. }  
  18.   
  19. int Animal::getAge()  
  20. {  
  21.     return this->age;  
  22. }  
  23.   
  24. void Animal::sound()  
  25. {  
  26.     printf("--Animal-- name: %s, age:%d\n", this->name, this->age );   
  27. }  


LuaAimal.h

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. #pragma once  
  2.   
  3. #ifndef __LUA_ANIMAL__  
  4. #define __LUA_ANIMAL__  
  5.   
  6. class Animal;  
  7.   
  8. class LuaAnimal  
  9. {  
  10. public:  
  11.     ~LuaAnimal(void);  
  12.     static void Register( lua_State *l );  
  13. private:  
  14.     static const char *className;  
  15.     static const luaL_reg methods[];  
  16.     static const luaL_reg methods_f[];  
  17.   
  18.     static int create( lua_State *l );  
  19.     static int gc_animal( lua_State *l );  
  20.     static Animal *getAnimal( lua_State *l );  
  21.   
  22.     static int sound( lua_State *l );  
  23.     static int setAge(lua_State *l);  
  24.     static int getAge(lua_State *l);  
  25. };  
  26.   
  27. #endif  


LuaAnimal.cpp

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. #include "stdafx.h"  
  2. #include "LuaAnimal.h"  
  3. #include "Animal.h"  
  4. #include "Utlis.h"  
  5.   
  6. const char *LuaAnimal::className = "Animal";  
  7. const luaL_reg LuaAnimal::methods[] = {  
  8.     {"sound", LuaAnimal::sound },  
  9.     {"setAge", LuaAnimal::setAge},  
  10.     {"getAge", LuaAnimal::getAge},  
  11.     {"__gc", LuaAnimal::gc_animal},  
  12.     {NULL,NULL}  
  13. };  
  14.   
  15. const luaL_reg LuaAnimal::methods_f[] = {  
  16.     { "create", LuaAnimal::create },  
  17.     { NULL, NULL}  
  18. };  
  19.   
  20. LuaAnimal::~LuaAnimal(void)  
  21. {  
  22. }  
  23.   
  24. void LuaAnimal::Register( lua_State *l )  
  25. {  
  26.     //1. new method table for l to save functions  
  27.     lua_newtable(l);  
  28.     int methodTable = lua_gettop(l);  
  29.   
  30.     //2.new metatable for L to save "__metatable", "__index",  "__gc", etc  
  31.     luaL_newmetatable(l, className );  
  32.     int metaTable = lua_gettop(l);  
  33.   
  34.     //3.0 metatable["__metatable"] = methodtable;  
  35.     lua_pushliteral( l, "__metatable" );  //remove \0  
  36.     lua_pushvalue( l, methodTable );  
  37.     lua_settable( l, metaTable );  
  38.   
  39.     //4.0 metatable["__index"] = methodtable  
  40.     lua_pushliteral( l, "__index" );  
  41.     lua_pushvalue( l, methodTable );  
  42.     lua_rawset( l, metaTable );  // the same as lua_settable(1,metatable)  
  43.   
  44.     //5.0 metatable["__gc"] = gc_animal  //will be called when lua_close(l)  
  45.     lua_pushliteral( l, "__gc" );   
  46.     lua_pushcfunction( l, LuaAnimal::gc_animal );  
  47.     lua_rawset( l, metaTable );  
  48.   
  49.     lua_pop(l,1);   //drop metatable  
  50.   
  51.     /*6.0 for object 
  52.     name -- null set object funtion to methodtable( the table on top ); 
  53.     eg: Animal a = Animal("xxx") 
  54.     a:func in this methodtable 
  55.     fill methodtable, is libname is not null, 
  56.     will create a table use the libname and push the table to stack*/  
  57.     luaL_openlib( l, NULL, methods, 0 );   
  58.     lua_pop(l,1);       //drop methodtable  
  59.   
  60.     /*7.1 for class: 
  61.     name = className, so this set function to "method_f" 
  62.     eg: Animal a = Animal:create( "xx" ); 
  63.         Animal:create() in this method_f tables 
  64.     */  
  65.     luaL_openlib( l, className, methods_f, 0 );  //push table[className] to stack  
  66.     lua_pop(l,1); //drop table[className]  
  67.   
  68.     /*7.2 for class: 
  69.     add global function "className", so we Animal() is a global function now 
  70.     eg: Animal a = Animal("xx") 
  71.         function Animal() in lua will call create in C++ 
  72.     */  
  73.     //lua_register(l, className, LuaAnimal::create );  
  74. }  
  75.   
  76. int LuaAnimal::create( lua_State *l )  
  77. {  
  78.     const char*name = lua_tostring(l,-1);  
  79.   
  80.     Animal *a = new Animal(name);  
  81.     void **p = (void**)lua_newuserdata( l, sizeof(void*));    
  82.     *p = a;  
  83.   
  84.     luaL_getmetatable( l, className );  
  85.     lua_setmetatable( l, -2 );  
  86.   
  87.     return 1;  
  88. }  
  89.   
  90. Animal* LuaAnimal::getAnimal( lua_State *l )  
  91. {  
  92.     luaL_checktype( l, 1, LUA_TUSERDATA ); //indicate what type to check  
  93.     void *ud = luaL_checkudata( l, 1, className );  
  94.     if( !ud )  
  95.         luaL_typerror( l, 1, className );  
  96.   
  97.     return *(Animal**)ud;  
  98. }  
  99.   
  100. int LuaAnimal::gc_animal( lua_State *l )  
  101. {  
  102.     Utlis::stackDump(l);  
  103.   
  104.     Animal *a = (Animal*)(*(void**)lua_touserdata(l,-1));  
  105.     delete a;  
  106.     return 0;  
  107. }  
  108.   
  109. int LuaAnimal::getAge( lua_State *l )  
  110. {  
  111.     Animal *a = getAnimal(l);  
  112.     lua_pushinteger(l, a->getAge());  
  113.     return 1;  
  114. }  
  115.   
  116. int LuaAnimal::setAge( lua_State *l )  
  117. {  
  118.     Animal *a = getAnimal(l);  
  119.     int age = luaL_checkint(l,2);  
  120.     a->setAge( age );  
  121.     return 0;  
  122. }  
  123.   
  124. int LuaAnimal::sound( lua_State *l )  
  125. {  
  126.     Animal *a = getAnimal(l);  
  127.     a->sound();  
  128.     return 0;  
  129. }  


工具类Utils,使用查看lua堆栈情况

Utils.h

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. #pragma once  
  2. #ifndef __UTLIS_H__  
  3. #define __UTLIS_H__  
  4.   
  5. class Utlis  
  6. {  
  7. public:  
  8.     Utlis(void);  
  9.     ~Utlis(void);  
  10.     static void stackDump( lua_State *l );  
  11. };  
  12.   
  13. #endif  


Utils.cpp

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. #include "stdafx.h"  
  2. #include "Utlis.h"  
  3.   
  4.   
  5. Utlis::Utlis(void)  
  6. {  
  7. }  
  8.   
  9.   
  10. Utlis::~Utlis(void)  
  11. {  
  12. }  
  13.   
  14. void Utlis::stackDump( lua_State *l )  
  15. {  
  16.     int i;  
  17.     int top = lua_gettop( l );  
  18.     printf("------start-----%d\n", top);  
  19.   
  20.     for( i = 1; i <= top; i++ )  
  21.     {  
  22.         int t = lua_type( l, i );  
  23.         printf("type: %s value:", lua_typename(l,t));  
  24.   
  25.         switch (t)  
  26.         {  
  27.         case LUA_TSTRING:  
  28.             printf("%s", lua_tostring(l,i));  
  29.             break;  
  30.         case LUA_TBOOLEAN:  
  31.             printf( lua_toboolean(l,i)? "true" : "false" );  
  32.             break;  
  33.         case LUA_TNUMBER:  
  34.             printf("%g", lua_tonumber(l,i));  
  35.             break;  
  36.   
  37.         default:  
  38.             printf("%s", lua_typename(l,t));  
  39.             break;  
  40.         }  
  41.         printf("\n");  
  42.     }  
  43.   
  44.     printf("------end----\n" );  
  45. }  


lua测试代码

main.lua

[plain] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. print( "test lua access C++ class" )  
  2.   
  3. local function main()  
  4.   --使用luaL_openlib( l, className, methods_f, 0 )注册,  
  5.   --Animal是个table, 调用create方法  
  6.   --local s = Animal.create("xx") --lua_gettop()=1 1:xx  
  7.   local s = Animal:create("xx") --lua_gettop()=2 1:table, 2:xx, 相比.create多了一个table,指Animal本身  
  8.   s:setAge(100)  
  9.   s:sound()  
  10.   
  11.   --使用lua_register(l, className, LuaAnimal::create )注册  
  12.   --Animal是个函数,直接调用方法  
  13.   
  14.    --local a = Animal("ww")    
  15.    --a:setAge(20)  
  16.    --a:sound()  
  17. end  
  18.   
  19. main()  


最后是C++测试代码

main.cpp

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
 
    1. // TestLua.cpp : 定义控制台应用程序的入口点。  
    2. //  
    3.   
    4. #include "stdafx.h"  
    5. #include "Utlis.h"  
    6. #include "LuaAnimal.h"  
    7.   
    8. using namespace std;  
    9.   
    10. int _tmain(int argc, _TCHAR* argv[])  
    11. {  
    12.     lua_State *l = lua_open();  
    13.     luaL_openlibs(l);  
    14.       
    15.     LuaAnimal::Register(l);  
    16.     Utlis::stackDump(l);  
    17.   
    18.     if( luaL_dofile( l, "main.lua" )){  // load and call  
    19.         Utlis::stackDump(l);  
    20.     }  
    21.     Utlis::stackDump(l);  
    22.   
    23.     system("pause");  
    24.     lua_close(l);  
    25.   
    26.     return 0;  
    27. }  
posted @ 2015-08-07 18:50  &&123  阅读(514)  评论(0编辑  收藏  举报