所以我正在阅读如何通过这个小博客教程为Lua创建和注册c ++类.
但是,尽管简单,信息丰富且易读,但它似乎是旧版本的Lua.
因此,某些功能/宏要么丢失,要么只有不同的签名.
在Lua C 5.2版中,以下代码是什么样的?
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <stringstream>
#include <string>
using namespace std;
// Just a useless test class
class MyClass
{
private:
int _X;
public:
MyClass(int x) : _X(x) {};
~MyClass() { Release() };
// Displays your number in a welcoming message box
void Hello()
{
stringstream ss;
ss << "Hello!" << endl << "Your number is: " << _X;
string s(ss.str());
MessageBoxA(NULL, s.c_str(), "MyClass", MB_ICONINFORMATION);
}
void Release() {
//release code goes here
}
};
// Functions that will create/destroy MyClass instances
static int newMyClass(lua_State* L)
{
int n = lua_gettop(L); // Number of arguments
if (n != 2)
return luaL_error(L, "Got %d arguments, expected 2 (class, x)", n);
// First argument is now a table that represent the class to instantiate
luaL_checktype(L, 1, LUA_TTABLE);
lua_newtable(L); // Create table to represent instance
// Set first argument of new to metatable of instance
lua_pushvalue(L, 1);
lua_setmetatable(L, -2);
// Do function lookups in metatable
lua_pushvalue(L, 1);
lua_setfield(L, 1, "__index");
// Allocate memory for a pointer to to object
MyClass** s = (MyClass**)lua_newuserdata(L, sizeof(MyClass*));
int x = luaL_checknumber(L, 2);
*s = new MyClass(x);
luaL_getmetatable(L, "Lua.MyClass");
lua_setmetatable(L, -2);
lua_setfield(L, -2, "__self");
return 1;
}
static int doSomethingMyClass(lua_State* L)
{
MyClass* c = nullptr;
checkUserData(L, "Lua.MyClass", c);
c->Hello();
return 0;
}
static int destroyMyClass(lua_State* L)
{
MyClass* c = nullptr;
checkUserData(L, "Lua.MyClass", c);
c->Release();
return 0;
}
// Functions that will show up in our Lua environment
static const luaL_Reg gMyClassFuncs[] = {
// Creation
{ "new", newMyClass) },
{ "hello", helloMyClass },
{ NULL, NULL }
};
static const luaL_Reg gDestroyMyClassFuncs[] = {
{"__gc", destroyMyClass},
{NULL, NULL}
};
// Registers the class for use in Lua
void registerMyClass(lua_State *L)
{
// Register metatable for user data in registry
luaL_newmetatable(L, "Lua.MyClass");
luaL_register(L, 0, gDestroyMyClassFuncs);
luaL_register(L, 0, gMyClassFuncs);
lua_pushvalue(L, -1);
lua_setfield(L, -2, "__index");
// Register the base class for instances of Sprite
luaL_register(L, "MyClass", gSpriteFuncs);
}
Run Code Online (Sandbox Code Playgroud)
基本上,这里的目标是能够在Lua中编写以下内容:
-- Create a new MyClass instance
local c = MyClass:new(5)
-- Show message
c:Hello() -- Should say something like "Hello! Your number is: 5"
Run Code Online (Sandbox Code Playgroud)
为了使这项工作适用于5.2,我需要改变什么?
该代码中唯一不属于Lua 5.2的函数是luaL_register.你应该使用luaL_setfuncs.
您还应该MyClass手动设置全局或local MyClass=require"MyClass"在Lua代码中使用,因为require不再设置全局变量.
如果你正在嵌入Lua,你可以编译它和你的代码-DLUA_COMPAT_MODULE并获得5.1函数.但是,如果您计划使用此版本,请考虑现在是将代码移至Lua 5.2的好时机.