2016-02-09 72 views
2

我在C++中製作一個GUI。將Lua函數傳遞給C++

我想要一個Lua腳本向C++註冊一個Lua函數,這樣當一個按鈕點擊被C++處理時,C++將調用一個已註冊的Lua函數。

我已經使用了以下SO張貼作爲指導:http://stackoverflow.com/questions/4928973/how-do-you-pass-a-lua-function-to-a-c-function-and-execute-the-lua-function-seve

出於某種原因,我的變化,這是行不通的。

這是我的Lua代碼:

-- this is button.setClickEvent 
function self.setClickEvent(eventFunction) 
    uiButtonSetClickEvent(self.id, eventFunction) 
end 

function buttonClick() 
    print("yay it worked!") 
end 

button.setClickEvent(buttonClick) 

這裏是C++

static int lua_uiButtonSetClickEvent(lua_State *L) 
{ 
    int argumentsCount = lua_gettop(L); 
    int argumentsMin = 2; 
    if(argumentsCount < argumentsMin) 
     cout << "Error at uiButtonSetClickEvent, incorrect number of arguments" << endl; 

    double buttonId = lua_tonumber(L, 1); 
    int event = luaL_ref(L, LUA_REGISTRYINDEX); 

    long i = uiButtonGetIndex(buttonId); 
    if(i != -1) 
    { 
     cout << "!!! Storing lua function reference" << endl; 
     uiButtons[i].luaClickEvent = event; 
     uiButtonSetClickEvent(buttonId, lua_uiButtonCallClickEvent); 
    } 

    return 0; 
} 

static void uiButtonSetClickEvent(double buttonId, void (&event)(double)) 
{ 
    long i = uiButtonGetIndex(buttonId); 
    if(i != -1) 
     uiButtons[i].clickEvent = event; 
} 

static void lua_uiButtonCallClickEvent(double buttonId) 
{ 
    long i = uiButtonGetIndex(buttonId); 
    if(i != -1) 
    { 
      lua_rawgeti(L, LUA_REGISTRYINDEX, uiButtons[i].luaClickEvent); 

      if (0 != lua_pcall(L, 0, 0, 0)) { 
      printf("Failed to call the callback!\n %s\n", lua_tostring(L, -1)); 
      return; 
      } 

      uiButtons[i].luaClickEvent = luaL_ref(L, LUA_REGISTRYINDEX); 
    } 
} 

發生的一切如預期的代碼,直到在該點

結果是中的分段錯誤lua_uiButtonCallClickEvent在以下行:

lua_rawgeti(L, LUA_REGISTRYINDEX, uiButtons[i].luaClickEvent); 

我在導之間注意到的唯一區別SO,我的實現,不僅通過Lua的功能,C++,也buttonId

我不知道參數偏移是否導致問題。

引用的Lua函數的整數是3

我曾嘗試研究的Lua的參考手冊,但都沒有成功。

我相信我所尋找的修復是微不足道的,我希望你能提供幫助。

感謝您閱讀

+0

也許你的Lua棧在調用'lua_rawgeti'時已經被破壞了? ** LUA_REGISTRYINDEX **不會變得無效,並且一個無效索引只會導致** nil **被推入堆棧(所以** lua_pcall **應該導致崩潰)。 – Youka

+0

lua_rawgeti之後我無法輸出到控制檯,因爲segfault因此它不是lua_pcall,但它不僅僅是lua_rawgeti,如果我嘗試使用任何lua_ *函數,當通過它的指針調用uiButtonCallClickEvent時,lua會落在它的臉上與segfault,所以它似乎有什麼問題之前,我通過它的指針調用C++函數。我正在使用GLFW庫,並且這個事件鏈源於對鼠標按鈕的glfw回調:'(glfw可能是問題所在,當然,如果我沒有使用glfw並且已經測試了我的代碼,工程 – Chris

+0

所以你是正確的,盧阿堆似乎已經無法訪問。 – Chris

回答

0

lua_close(L)被稱爲太早,這破壞了LUA堆棧。