Lua 與 C 擴充 -將 C++ 指標傳去給 Lua

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()

執行結果

回到目錄
https://husking-studio.com/extending-lua-with-c

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *