使用LUA userdata手动绑定C++对象
2016-08-21 01:56
381 查看
人老了容易忘记以前做过事情,第一次写自己的博客!
本文使用的LUA5.1版本
lua.hpp
Student.h
Student.cpp
main.lua
main.cpp
特别注意: 使用lua userdata创建 C++ Student对象生命周期的问题!我使用lua gc删除C++ Student对象!
关于生命周期可以参考cocos2d-x自动释放池,也可以考虑一下云风大神博文!
本文使用的LUA5.1版本
lua.hpp
// lua.hpp // Lua header files for C++ // <<extern "C">> not supplied automatically because Lua also compiles as C++ #ifdef __cplusplus extern "C" { #endif #include "lua.h" #include "lualib.h" #include "lauxlib.h" #ifdef __cplusplus } #endif
Student.h
#ifndef __STUDENT_H_ #define __STUDENT_H_ #include "lua.hpp" class Student { public: Student(); void SetAge(int nAge); int GetAge(); int m_nAge; }; #ifdef __cplusplus extern "C" { #endif int luaopen_student(lua_State *L); #ifdef __cplusplus } #endif #endif
Student.cpp
#include "Student.h" Student::Student() { m_nAge = 0; } void Student::SetAge(int nAge) { this->m_nAge = nAge; } int Student::GetAge() { return this->m_nAge; } static int Create(lua_State *L) { Student **s = (Student**)lua_newuserdata(L, sizeof(Student*)); *s = new Student; // 将userdata自定义数据与元表Meta_Student相关联 luaL_getmetatable(L, "Meta_Student"); lua_setmetatable(L, -2); return 1; } static int SetAge(lua_State *L) { Student **s = (Student**)luaL_checkudata(L, 1, "Meta_Student"); luaL_argcheck(L, s != NULL, 1, "invalid user data"); int nAge = (int)lua_tonumber(L, -1); (*s)->SetAge(nAge); return 0; } static int GetAge(lua_State *L) { Student **s = (Student**)luaL_checkudata(L, 1, "Meta_Student"); luaL_argcheck(L, s != NULL, 1, "invalid user data"); lua_pushnumber( L, (lua_Number)((*s)->GetAge()) ); return 1; } static int AutoDel(lua_State *L) { Student **s = (Student**)luaL_checkudata(L, 1, "Meta_Student"); luaL_argcheck(L, s != NULL, 1, "invalid user data"); delete (*s); return 0; } int luaopen_student(lua_State *L) { luaL_Reg reg[] = { {"Create", Create }, {NULL,NULL}, }; // 创建名字为“Meta_Student”元表 luaL_newmetatable(L, "Meta_Student"); //修改元表“Meta_Student”查找索引,把它指向“Meta_Student”自身 lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); // GetAge方法 lua_pushcfunction(L, GetAge); lua_setfield(L, -2, "GetAge"); // SetAge方法 lua_pushcfunction(L, SetAge); lua_setfield(L, -2, "SetAge"); // 自动删除,如果表里有__gc,Lua的垃圾回收机制会调用它。 lua_pushcfunction(L, AutoDel); lua_setfield(L,-2,"__gc"); // 注册reg中的方法到Lua中(“Student”相当于类名),reg中的方法相当于Student成员函数 luaL_register(L, "Student", reg); return 1; }
main.lua
print(Student) --[[ 1.打印Student地址 2.打印nil --> luaL_register(L, "Student", reg); 这段代码没有执行成功 ]] local p = Student.Create() --[[ 调用C++代码: static int Create(lua_State *L) { Student **s = (Student**)lua_newuserdata(L, sizeof(Student*)); *s = new Student; // 将userdata自定义数据与元表Meta_Student相关联 luaL_getmetatable(L, "Meta_Student"); lua_setmetatable(L, -2); return 1; } @retrun p-> Student* ]] p:SetAge(1200) -- 调用方法1 p.SetAge(p, 1000) -- 调用方法2 --[[ p:SetAge() p(userdata)没有注册SetAge方法, 就会寻找与p(userdata)相关联的元表Meta_Student有SetAge方法!并调用! 调用C++代码: static int SetAge(lua_State *L) { Student **s = (Student**)luaL_checkudata(L, 1, "Meta_Student"); luaL_argcheck(L, s != NULL, 1, "invalid user data"); int nAge = (int)lua_tonumber(L, -1); (*s)->SetAge(nAge); return 0; } ]] print(p:GetAge()) --[[ 调用C++代码: static int GetAge(lua_State *L) { Student **s = (Student**)luaL_checkudata(L, 1, "Meta_Student"); luaL_argcheck(L, s != NULL, 1, "invalid user data"); lua_pushnumber( L, (lua_Number)((*s)->GetAge()) ); return 1; } ]]
main.cpp
// MyCma.cpp : 定义控制台应用程序的入口点。 // //#include <SDKDDKVer.h> #include <stdio.h> #include <tchar.h> #include <windows.h> #include <string> #include "lua.hpp" #include "Student.h" int _tmain(int argc, _TCHAR* argv[]) { lua_State* L = luaL_newstate(); luaL_openlibs(L); luaopen_student(L); luaL_dofile(L, "main.lua"); lua_close(L); system("pause"); return 0; }
特别注意: 使用lua userdata创建 C++ Student对象生命周期的问题!我使用lua gc删除C++ Student对象!
关于生命周期可以参考cocos2d-x自动释放池,也可以考虑一下云风大神博文!
相关文章推荐
- 使用LUA userdata手动绑定C++对象
- lua_newuserdata简单使用
- Lua 中使用面向对象(续)--newproxy生成userdata使用__gc
- lua: userdata的metatable使用
- <转> lua: userdata的metatable使用
- lua——userdata使用
- lua userdata 使用
- Lua 中使用面向对象(续)--newproxy生成userdata使用__gc
- asp.net中ListView控件动态绑定数据源后,使用DataPager出现错误的原因及解决办法
- UserData使用总结[转载-lanyu]
- UserData使用总结
- [Cocoa]深入浅出 Cocoa 之 Core Data(3)- 使用绑定
- WPF中使用ObjectDataProvider绑定方法
- asp.net中ListView控件动态绑定数据源后,使用DataPager出现错误的原因及解决办法
- [Cocoa]深入浅出 Cocoa 之 Core Data(4)- 使用绑定
- 使用ModelBinder绑定IPrincipal (User)简化ASP.NET MVC单元测试
- WPF程序设计指南第24张样式中DataTrigger中使用绑定的例子
- DHTMLX TREE userdata 使用
- 使用userdata保持TreeView展开/折叠状态
- GridView绑定字段格式DataFormatString的使用