Lua 與 C 擴充 -將 C++ 指標傳去給 Lua
環境
windows 11 64bit
Visual Studio 2022
Lua 5.4.6
下載這個檔案 – lunar.h
https://www.dropbox.com/scl/fi/wi9sxxuxbb3dunpl5mjll/lunar.h?dl=0&rlkey=ope8e6th3gbunwq59g7t85q4t
object.h
#ifndef __OBJECT_H
#define __OBJECT_H
#include <string>
class GameObject
{
public:
GameObject(int x);
~GameObject();
private:
int attribute;
std::string message;
public:
void setMessage(const char* new_message);
const char* getMessage();
int getAttr();
void setAttr(int set);
};
#endif
object.cpp
#include "object.h"
GameObject::GameObject(int x)
{
attribute = x;
}
GameObject::~GameObject()
{
printf("deleted Object\n");
//printf("deleted Object (%p)\n", this);
}
void GameObject::setMessage(const char* new_message)
{
message.assign(new_message);
}
const char* GameObject::getMessage()
{
return message.c_str();
}
int GameObject::getAttr()
{
return (int)attribute;
}
void GameObject::setAttr(int set)
{
attribute = set;
}
luaobject.h
#ifndef __LUAOBJECT_H
#define __LUAOBJECT_H
#include "lunar.h"
#include "object.h"
class LuaGameObject
{
public:
// Constants
static const char className[];
static Lunar<LuaGameObject>::RegType methods[];
// Initialize the pointer
LuaGameObject(lua_State* L);
~LuaGameObject();
void setObject(lua_State* L);
// Methods we will need to use
int getAttr(lua_State* L);
int setAttr(lua_State* L);
int getMessage(lua_State* L);
int setMessage(lua_State* L);
private:
// The pointer to the 'real object' defined in object.cc
GameObject* real_object;
};
#endif
luaobject.cpp
#include "luaobject.h"
// Define the Lua ClassName
const char LuaGameObject::className[] = "LuaGameObject";
// Define the methods we will expose to Lua
// Check luaobject.h for the definitions...
#define method(class, name) {#name, &class::name}
Lunar<LuaGameObject>::RegType LuaGameObject::methods[] = {
method(LuaGameObject, setAttr),
method(LuaGameObject, getAttr),
method(LuaGameObject, getMessage),
method(LuaGameObject, setMessage),
{0,0}
};
LuaGameObject::LuaGameObject(lua_State* L)
{
real_object = (GameObject*)lua_touserdata(L, 1);
}
void LuaGameObject::setObject(lua_State* L)
{
real_object = (GameObject*)lua_touserdata(L, 1);
}
int LuaGameObject::setAttr(lua_State* L)
{
real_object->setAttr((int)luaL_checknumber(L, 1));
return 0;
}
int LuaGameObject::getAttr(lua_State* L)
{
lua_pushnumber(L, real_object->getAttr());
return 1;
}
int LuaGameObject::setMessage(lua_State* L)
{
real_object->setMessage(lua_tostring(L, 1));
return 0;
}
int LuaGameObject::getMessage(lua_State* L)
{
lua_pushstring(L, real_object->getMessage());
return 1;
}
LuaGameObject::~LuaGameObject()
{
printf("deleted Lua Object (%p)\n", this);
}
main.cpp
#include <iostream>
#include <stdio.h>
#include "object.h"
#include "luaobject.h"
using namespace std;
#include <K:\Lua\546\lib17\include\lua.hpp>
#ifdef _WIN64
#ifdef _DEBUG
#pragma comment(lib,"K:\\Lua\\546\\lib17\\x64\\Debug\\lua54.lib")
#else
#pragma comment(lib,"K:\\Lua\\546\\lib17\\x64\\Release\\lua54.lib")
#endif
#else
#ifdef _DEBUG
#pragma comment(lib,"K:\\Lua\\546\\lib17\\x86\\Debug\\lua54.lib")
#else
#pragma comment(lib,"K:\\Lua\\546\\lib17\\x86\\Release\\lua54.lib")
#endif
#endif
lua_State* LuaOpen()
{
//lua_State* pLua = lua_open();
lua_State* pLua = luaL_newstate();
if (!pLua)
{
cout << "Failed to open Lua.\n" << endl;
return 0;
}
luaL_openlibs(pLua);
return pLua;
}
int main()
{
lua_State *L = LuaOpen();
Lunar<LuaGameObject>::Register(L);
GameObject *pTemp = new GameObject(20);
pTemp->setMessage("I'm set in C++");
lua_pushlightuserdata(L, (void*)pTemp);
lua_setglobal(L,"go");
cout << "--call lua--" << endl;
luaL_dofile(L, "gameobject.lua");
cout << "--after lua--" << endl;
cout<<pTemp->getAttr()<<endl;
cout<<pTemp->getMessage()<<endl;
delete pTemp;
lua_close(L);
system("pause");
return 0;
}
gameobject.lua
-- This function uses the getX() methods in our target class
function LuaGameObject:show()
print("LuaGameObject attribute")
print(b:getAttr())
print(b:getMessage())
end
-- Start up a new LuaGameObject wrapper class and pass the global gameobject
-- C++ lightuserdata pointer into it
b = LuaGameObject(go)
-- Call a Lua function on this object
b:show()
print("--change in lua--")
b:setAttr(120)
b:setMessage('Hey, Lua changes a string!')
b:show()
執行結果