• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
    • 軟件測試技術
    • 軟件測試博客
    • 軟件測試視頻
    • 開源軟件測試技術
    • 軟件測試論壇
    • 軟件測試沙龍
    • 軟件測試資料下載
    • 軟件測試雜志
    • 軟件測試人才招聘
      暫時沒有公告

    字號: | 推薦給好友 上一篇 | 下一篇

    向 lua 虛擬機傳遞信息

    發布: 2007-7-04 20:48 | 作者: admin | 來源:  網友評論 | 查看: 47次 | 進入軟件測試論壇討論

    領測軟件測試網

    當程序邏輯交給腳本跑了以后,C/C++ 層就只需要把必要的輸入信息傳入虛擬機就夠了。當然,我們也需要一個高效的傳遞方法。
    
    以向 lua 虛擬機傳遞鼠標坐標信息為例,我們容易想到的方法是,定義一個 C 函數 get_mouse_pos 。當 lua 腳本中需要取得鼠標坐標的時候,就可以調用這個函數。
    
    但這并不是一個好方法,因為每次獲取鼠標坐標,都需要在虛擬機和 native code 間做一次切換。我們應該尋求更高效的方案。
    
    編寫腳本的人可以只獲取一次鼠標坐標,然后把數據放進一組全局變量。在一個運行片內,不再調用 get_mouse_pos 函數,而是通過訪問全局變量來得到鼠標的位置。
    
    從這個方案,我們可以引申開,其實這個全局變量可以由 C 程序主動設置,在 native code 的運行片中,Windows 消息處理完后,直接講鼠標信息設入 lua 虛擬機。代碼類似這樣的。
    
    lua_pushstring(L,"MOUSE_X");
    lua_pushnumber(L,mouse_x);
    lua_settable(L,LUA_GLOBALSINDEX);
    
    lua_pushstring(L,"MOUSE_Y");
    lua_pushnumber(L,mouse_y);
    lua_settable(L,LUA_GLOBALSINDEX);
    
    但是這里,依舊存在一個效率問題,那就是 lua_pushstring 。我們知道,lua 虛擬機中,每次產生一個 string ,都需要查對 string 在虛擬機中是否存在相同的拷貝,如果存在,就直接引用已有的;如果不存在,則產生一份新的拷貝。
    
    這里,MOUSE_X 和 MOUSE_Y 兩個 string 除了第一次運行,以后都是存在于 lua 虛擬機中的,雖然不會產生新的 string,但查找和比較字符串依然會消耗一定的時間。下面,我們來優化這個 lua_pushstring 操作。
    
    我們可以在程序開始階段,創建出這兩個 string ,并且在 C 中保留引用。
    lua_pushstring(L,"MOUSE_X");
    _mouse_x_ref=lua_ref(L,-1);
    lua_pushstring(L,"MOUSE_Y");
    _mouse_y_ref=lua_ref(L,-1);
    
    那么,以后運行時就不需要再做 lua_pushstring 操作了,而改成相對較快的 lua_getref 操作。
    
    lua_getref(L,_mouse_x_ref);
    lua_pushnumber(L,mouse_x);
    lua_settable(L,LUA_GLOBALSINDEX);
    
    lua_getref(L,_mouse_y_ref);
    lua_pushnumber(L,mouse_y);
    lua_settable(L,LUA_GLOBALSINDEX);
    
    lua_getref 之所以相對快一些,是因為 lua 對數字做 key 的 table 操作有優化處理,直接變成一次指針操作。而 ref 就是記在一張全局表中的。而且 lua_getref 不需要 lua_pushstring 做過的 strcmp 操作。
    
    那么這個方法還沒有優化余地呢?答案還是有。
    
    我們其實可以寫一個 lua 程序,放在一個單獨的文件(mouse.lua)中,程序很短:
    
    return funtion(mx,my) MOUSE_X,MOUSE_Y=mx,my end
    
    我們在程序啟動的時候運行
    lua_dofile(L,"mouse.lua");
    _mouse_set_ref=lua_ref(L,-1);
    
    那么,在設置鼠標坐標的時候就可以簡單的做如下操作:
    lua_getref(L,_mouse_set_ref);
    lua_pushnumber(L,mouse_x);
    lua_pushnumber(L,mouse_y);
    lua_call(L,2,0);
    
    這個方案只需要保留一個函數的 ref ,并且把設置的工作交給了虛擬機中的偽指令。單從這個例子(僅僅 MOUSE_X,MOUSE_Y兩個需要傳遞的信息)來看,不能說明后者的效率更高一些,畢竟 lua_call 也有額外的消耗。但是,最后一個方案更加靈活,對于native code 向虛擬機更多數據的交換采用這種方案更加簡潔。
    
    ps. lua_ref 的東西,最后要記得調用 lua_unref 解引用。

    延伸閱讀

    文章來源于領測軟件測試網 http://www.kjueaiud.com/


    關于領測軟件測試網 | 領測軟件測試網合作伙伴 | 廣告服務 | 投稿指南 | 聯系我們 | 網站地圖 | 友情鏈接
    版權所有(C) 2003-2010 TestAge(領測軟件測試網)|領測國際科技(北京)有限公司|軟件測試工程師培訓網 All Rights Reserved
    北京市海淀區中關村南大街9號北京理工科技大廈1402室 京ICP備2023014753號-2
    技術支持和業務聯系:info@testage.com.cn 電話:010-51297073

    軟件測試 | 領測國際ISTQBISTQB官網TMMiTMMi認證國際軟件測試工程師認證領測軟件測試網

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>