人老了容易忘记以前做过事情,第一次写自己的博客!
本文使用的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
- #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对象!