使用LUA userdata手动绑定C++对象

人老了容易忘记以前做过事情,第一次写自己的博客! 


本文使用的LUA5.1版本


lua.hpp

[cpp]  view plain  copy
  1. // lua.hpp  
  2. // Lua header files for C++  
  3. // <<extern "C">> not supplied automatically because Lua also compiles as C++  
  4.   
  5. #ifdef __cplusplus    
  6. extern "C" {  
  7. #endif  
  8.     #include "lua.h"  
  9.     #include "lualib.h"  
  10.     #include "lauxlib.h"  
  11. #ifdef __cplusplus  
  12. }  
  13. #endif  

Student.h

[cpp]  view plain  copy
  1. #ifndef __STUDENT_H_  
  2. #define __STUDENT_H_  
  3.   
  4.   
  5. #include "lua.hpp"  
  6.   
  7. class Student  
  8. {  
  9. public:  
  10.     Student();  
  11.     void SetAge(int nAge);  
  12.     int GetAge();  
  13.   
  14.     int m_nAge;  
  15. };  
  16.   
  17.   
  18. #ifdef __cplusplus  
  19. extern "C" {  
  20. #endif  
  21.     int luaopen_student(lua_State *L);  
  22. #ifdef __cplusplus  
  23. }  
  24. #endif  
  25.   
  26.   
  27.   
  28.   
  29. #endif  


Student.cpp

[cpp]  view plain  copy
  1. #include "Student.h"  
  2.   
  3. Student::Student()  
  4. {  
  5.     m_nAge = 0;  
  6. }  
  7.   
  8. void Student::SetAge(int nAge)  
  9. {  
  10.     this->m_nAge = nAge;  
  11. }  
  12.   
  13.   
  14. int Student::GetAge()  
  15. {  
  16.     return this->m_nAge;  
  17. }  
  18.   
  19. static int Create(lua_State *L) {  
  20.     Student **s =  (Student**)lua_newuserdata(L, sizeof(Student*));  
  21.     *s = new Student;  
  22.   
  23.     // 将userdata自定义数据与元表Meta_Student相关联  
  24.     luaL_getmetatable(L, "Meta_Student");  
  25.     lua_setmetatable(L, -2);  
  26.   
  27.     return 1;  
  28. }  
  29.   
  30.   
  31. static int SetAge(lua_State *L) {  
  32.     Student **s = (Student**)luaL_checkudata(L, 1, "Meta_Student");  
  33.     luaL_argcheck(L, s != NULL, 1, "invalid user data");  
  34.   
  35.     int nAge = (int)lua_tonumber(L, -1);  
  36.     (*s)->SetAge(nAge);  
  37.   
  38.     return 0;  
  39. }  
  40.   
  41. static int GetAge(lua_State *L) {  
  42.     Student **s = (Student**)luaL_checkudata(L, 1, "Meta_Student");  
  43.     luaL_argcheck(L, s != NULL, 1, "invalid user data");  
  44.   
  45.     lua_pushnumber( L, (lua_Number)((*s)->GetAge()) );  
  46.   
  47.     return 1;  
  48. }  
  49.   
  50. static int AutoDel(lua_State *L) {  
  51.     Student **s = (Student**)luaL_checkudata(L, 1, "Meta_Student");  
  52.     luaL_argcheck(L, s != NULL, 1, "invalid user data");  
  53.   
  54.     delete (*s);  
  55.   
  56.     return 0;  
  57. }  
  58.   
  59.   
  60. int luaopen_student(lua_State *L)   
  61. {  
  62.     luaL_Reg reg[] =   
  63.     {  
  64.         {"Create", Create },  
  65.         {NULL,NULL},  
  66.     };  
  67.   
  68.     // 创建名字为“Meta_Student”元表  
  69.     luaL_newmetatable(L, "Meta_Student");  
  70.   
  71.     //修改元表“Meta_Student”查找索引,把它指向“Meta_Student”自身  
  72.     lua_pushvalue(L, -1);  
  73.     lua_setfield(L, -2, "__index");  
  74.   
  75.     // GetAge方法  
  76.     lua_pushcfunction(L, GetAge);  
  77.     lua_setfield(L, -2, "GetAge");  
  78.   
  79.     // SetAge方法  
  80.     lua_pushcfunction(L, SetAge);  
  81.     lua_setfield(L, -2, "SetAge");  
  82.   
  83.     // 自动删除,如果表里有__gc,Lua的垃圾回收机制会调用它。  
  84.     lua_pushcfunction(L, AutoDel);  
  85.     lua_setfield(L,-2,"__gc");  
  86.   
  87.     // 注册reg中的方法到Lua中(“Student”相当于类名),reg中的方法相当于Student成员函数  
  88.     luaL_register(L, "Student", reg);  
  89.   
  90.     return 1;  
  91. }  

main.lua

[plain]  view plain  copy
  1. print(Student)    
  2. --[[   
  3.     1.打印Student地址  
  4.     2.打印nil --> luaL_register(L, "Student", reg); 这段代码没有执行成功  
  5. ]]  
  6.   
  7. local p = Student.Create()  
  8. --[[  
  9. 调用C++代码:  
  10. static int Create(lua_State *L) {  
  11.     Student **s =  (Student**)lua_newuserdata(L, sizeof(Student*));  
  12.     *s = new Student;  
  13.   
  14.     // 将userdata自定义数据与元表Meta_Student相关联  
  15.     luaL_getmetatable(L, "Meta_Student");  
  16.     lua_setmetatable(L, -2);  
  17.   
  18.     return 1;  
  19. }  
  20.   
  21. @retrun p-> Student*  
  22. ]]  
  23.   
  24. p:SetAge(1200)     -- 调用方法1  
  25. p.SetAge(p, 1000)   -- 调用方法2  
  26. --[[  
  27. p:SetAge() p(userdata)没有注册SetAge方法, 就会寻找与p(userdata)相关联的元表Meta_Student有SetAge方法!并调用!  
  28.   
  29. 调用C++代码:  
  30. static int SetAge(lua_State *L) {  
  31.     Student **s = (Student**)luaL_checkudata(L, 1, "Meta_Student");  
  32.     luaL_argcheck(L, s != NULL, 1, "invalid user data");  
  33.   
  34.     int nAge = (int)lua_tonumber(L, -1);  
  35.     (*s)->SetAge(nAge);  
  36.   
  37.     return 0;  
  38. }  
  39.   
  40. ]]  
  41.   
  42.   
  43. print(p:GetAge())  
  44. --[[  
  45. 调用C++代码:  
  46. static int GetAge(lua_State *L) {  
  47.     Student **s = (Student**)luaL_checkudata(L, 1, "Meta_Student");  
  48.     luaL_argcheck(L, s != NULL, 1, "invalid user data");  
  49.   
  50.     lua_pushnumber( L, (lua_Number)((*s)->GetAge()) );  
  51.   
  52.     return 1;  
  53. }  
  54. ]]  


main.cpp

[cpp]  view plain  copy
  1. // MyCma.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. //#include <SDKDDKVer.h>  
  5. #include <stdio.h>  
  6. #include <tchar.h>  
  7. #include <windows.h>  
  8. #include <string>  
  9. #include "lua.hpp"  
  10. #include "Student.h"  
  11.   
  12.   
  13. int _tmain(int argc, _TCHAR* argv[])  
  14. {  
  15.   
  16.     lua_State* L = luaL_newstate();  
  17.     luaL_openlibs(L);  
  18.     luaopen_student(L);  
  19.     luaL_dofile(L, "main.lua");  
  20.     lua_close(L);  
  21.   
  22.     system("pause");  
  23.   
  24.     return 0;  
  25. }  

特别注意: 使用lua userdata创建 C++  Student对象生命周期的问题!我使用lua gc删除C++  Student对象!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值