使用绑定C++函数并调用接受类参数的Lua函数。
2014-8-26 5:7:51
收藏:0
阅读:98
评论:1
我一直在研究 Lua/C++,并且有一个关于设计的问题,希望能得到一些帮助。
我的需求:
我希望我的 C++ 类(由 C++ 创建和销毁)能够使用自身作为参数调用 Lua 函数。
例如:
object.h
class Object
{
public:
Object(const std::string &onLoad, const std::string &onEvent);
~Object();
void OnLoad();
void RegisterEvent(const std::string &eventID);
void OnEvent(const std::string &eventID);
void SetValue(int value);
private:
int m_value;
std::string m_onLoad;
std::string m_onEvent;
};
object.cpp
Object::Object(const std::string &onLoad, const std::string &onEvent)
: m_value(0)
, m_onLoad(onLoad)
, m_onEvent(onEvent)
{
}
Object::~Object()
{
GAME->GetEventManager()->UnregisterListener(this);
}
void Object::OnLoad()
{
//
// 调用 Lua 函数 [名称存储在:m_onLoad 中]
// 例如:m_onLoad = Object_OnLoad
// 在 Lua 中 ->
// function Object_OnLoad(object)
//
}
void Object::RegisterEvent(const std::string &eventID)
{
GAME->GetEventManager()->RegisterEvent(this, eventID);
}
void Object::OnEvent()
{
//
// 调用 Lua 函数 [名称存储在:m_onEvent 中]
// 例如:m_onEvent = Object_OnEvent
// 在 Lua 中 ->
// function Object_OnEvent(object, eventID)
//
}
void Object::SetValue(int value)
{
m_value = value;
}
script.lua
function Object_OnLoad(object)
object:RegisterEvent("EVENT_CURRENT_HEALTH_CHANGED")
end
function Object_OnEvent(object, eventID)
if (eventID == "EVENT_CURRENT_HEALTH_CHANGED")
object:SetValue(GetCurrentHealth());
end
test.cpp
Object *pTest = new Object("Object_OnLoad", "Object_OnEvent");
pTest->OnLoad();
GAME->GetEventManager()->TriggerEvent(CEvent("EVENT_CURRENT_HEALTH_CHANGED"));
delete pTest;
阅读一些内容之后:
从我所读的内容来看,没有直接的方法可以分配 C++ 类实例函数。需要使用非成员函数。表被用于跟踪函数。
我的问题:
- 当调用 Lua 函数(例如 Object_OnEvent(object, eventID) 等)时,我应该推送什么参数?是对象的指针吗?
- Lua 如何了解对象设计?
- 每个对象或实例需要一个表吗?
- 我是否需要再次复制我打算在 Lua 中使用的所有函数,以作为常规函数,获取指针来调用它?
最后可能只有一个问题:
- 是否有任何地方可以获取有关我上面描述的目标的更多信息。
我可能会回到第一步,再次尝试吸收这些信息。我还是要发帖的。如果我设置好了,我会回复自己。
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
有许多问题,但原则上,如果我理解您的意思正确,您想要将C++类绑定到Lua,具有共享对象生命周期和自动垃圾回收功能,并且能够调用在C++侧创建的对象上的Lua函数。
这可以使用低级粘合代码或专用绑定库(例如LuaBridge和LuaState)实现。为了方便和快速原型设计,我的答案中使用了LuaState。
尚不清楚您为什么要在Lua中定义一个无足轻重的函数,例如
Object_OnLoad以从C++中调用它,该函数将调用在C++侧创建的同一范围内的对象的方法。我猜您的代码中有更复杂的情况,因此这种Lua使用模式是合理的。在这种情况下,针对每个问题:组成部分
将类绑定到Lua
这是一种声明性绑定,您可以在调用其他Lua函数之前调用它一次
void luabridge_bind(lua_State *L) { luabridge::getGlobalNamespace(L) .beginClass<MyObject>("MyObject") .addConstructor<void(*)(), RefCountedPtr<MyObject> /* 创建策略 */ >() .addFunction("RegisterEvent", &MyObject::RegisterEvent) .endClass() ; }要执行绑定:
lua::State state; luabridge_bind(state.getState());在C++侧对象上调用lua函数
目前,LuaState无法在调用参数中使用对象,而基元类型可以,例如从readme中:
state.doString("function add(x, y) return x + y end"); int result = state["add"](1,2);但是,一个人可以在全局范围内暂时创建一个变量实例(小心名称冲突)并在其上调用函数。
准备脚本:
static const char *script = "function Object_OnLoad(object)\n" " object:RegisterEvent('EVENT_CURRENT_HEALTH_CHANGED')\n" "end" ; state.doString(script);创建自动生命周期管理的对象:
auto my_obj = RefCountedPtr<MyObject>(new MyObject);在对象上调用lua函数:
SetGlobal(state.getState(), "my_obj", my_obj); state.doString("Object_OnLoad(my_obj); my_obj = nil");其中
SetGlobal可以看起来像这样:template <typename T> void SetGlobal(lua_State* L, const char *name, T value) { luabridge::push(L, value); lua_setglobal(L, name); }一个完整的示例和注释
您可以在Github上找到整个示例代码:try_luabridge.cpp
它已在Travis CI上编译和运行。
可能性是无限的。您如何结构化代码取决于您,因此,自然地,此答案不会提供立即符合您需求的代码。但是,我鼓励您阅读Programming in Lua以及LuaBridge和LuaState手册,以更好地了解可用的可能性。