簡體   English   中英

綁定 C++ 函數並以類為參數調用 Lua 函數

[英]Binding C++ functions & calling Lua functions with class as parameter

我一直在閱讀有關 Lua/C++ 的文章,我有一個關於設計的問題,希望能得到一些幫助。

我想要的是:

我希望我的 C++ 類(由 C++ 創建和銷毀)能夠使用自身作為參數調用 Lua 函數。

例如。

對象.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;
};

對象.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()
{
    //
    // call lua function [name store in: m_onLoad]
    // eg. m_onLoad = Object_OnLoad
    // in lua ->
    // function Object_OnLoad(object)
    //
}

void Object::RegisterEvent(const std::string & eventID)
{
    GAME->GetEventManager()->RegisterEvent(this, eventID);
}

void Object::OnEvent()
{
    //
    // call lua function [name store in: m_onEvent]
    // eg. m_onEvent = Object_OnEvent
    // in lua ->
    // function Object_OnEvent(object, eventID)
    //
}

void Object::SetValue(int value)
{
    m_value = value;
}

腳本文件

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

測試.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 中再次使用的所有函數作為獲取 ptr 的普通函數來調用它

作為最后一個可能的單一問題:

  • 有什么地方可以讓我獲得更多關於我試圖實現的上述目標的信息。

我可能會回到第一步,再次嘗試吸收這些信息。 我仍然不想發表我的帖子。 如果我設置了它,我會自己發帖。

有很多問題,但原則上,如果我理解正確,您希望將 C++ 類綁定到 Lua ,具有共享對象生存期和自動垃圾收集,並且能夠在 C++ 端創建的對象上調用 Lua 函數。

這一切都可以通過低級膠水代碼或專用綁定庫(例如LuaBridgeLuaState )實現 為了方便和快速原型設計,我的答案中使用了 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> /* creation policy */ >()
  .addFunction("RegisterEvent", &MyObject::RegisterEvent)
 .endClass()
 ;
}

要執行綁定:

 lua::State state;
 luabridge_bind(state.getState());

在 C++ 端對象上調用 lua 函數

不幸的是,LuaState 目前無法在調用參數中使用對象,而原語可以工作,即來自自述文件:

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 手冊,以便更好地了解您手頭的可能性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM