個人面試筆記:Lua與C++調用相關

1、lua虛擬機和C++相互調用、lua設計基礎的相關博客,供以後複習:
http://cn.cocos2d-x.org/tutorial/show?id=1474
http://blog.csdn.net/ym012/article/details/7209637
http://www.cnblogs.com/sifenkesi/p/3876745.html
http://my.oschina.net/xlplbo/blog/314956
http://blog.csdn.net/dongdongdongjl/article/details/8629704


2、本人的環境文檔:鏈接:http://pan.baidu.com/s/1o6FROMY 密碼:o7vt

或者:https://github.com/wjingzhe/LuaCppSrc

直接使用源碼配置。luac.c和lua.c相關說明參照:
http://blog.csdn.net/dongdongdongjl/article/details/8629704


3、分析文章待續,先熟悉lua機的源碼。cocos2d-x中,添加C++和luaScript的橋接函數,比如:
int lua_cocos2dx_3d_Skeleton3D_getBoneByName(lua_State* tolua_S)
{
    int argc = 0;
    cocos2d::Skeleton3D* cobj = nullptr;
    bool ok  = true;


#if COCOS2D_DEBUG >= 1
    tolua_Error tolua_err;
#endif




#if COCOS2D_DEBUG >= 1
    if (!tolua_isusertype(tolua_S,1,"cc.Skeleton3D",0,&tolua_err)) goto tolua_lerror;
#endif


    cobj = (cocos2d::Skeleton3D*)tolua_tousertype(tolua_S,1,0);


#if COCOS2D_DEBUG >= 1
    if (!cobj) 
    {
        tolua_error(tolua_S,"invalid 'cobj' in function 'lua_cocos2dx_3d_Skeleton3D_getBoneByName'", nullptr);
        return 0;
    }
#endif


    argc = lua_gettop(tolua_S)-1;
    if (argc == 1) 
    {
        std::string arg0;


        ok &= luaval_to_std_string(tolua_S, 2,&arg0, "cc.Skeleton3D:getBoneByName");
        if(!ok)
        {
            tolua_error(tolua_S,"invalid arguments in function 'lua_cocos2dx_3d_Skeleton3D_getBoneByName'", nullptr);
            return 0;
        }
        cocos2d::Bone3D* ret = cobj->getBoneByName(arg0);
        object_to_luaval<cocos2d::Bone3D>(tolua_S, "cc.Bone3D",(cocos2d::Bone3D*)ret);
        return 1;
    }
    luaL_error(tolua_S, "%s has wrong number of arguments: %d, was expecting %d \n", "cc.Skeleton3D:getBoneByName",argc, 1);
    return 0;


#if COCOS2D_DEBUG >= 1
    tolua_lerror:
    tolua_error(tolua_S,"#ferror in function 'lua_cocos2dx_3d_Skeleton3D_getBoneByName'.",&tolua_err);
#endif


    return 0;
}


4、前幾天面試遺留:
1)lua的table本身是由兩塊內存組成,一塊是連續的array,另外一塊則是hashTable實現的。因爲沒看過源碼不確認數組這塊的存儲,就沒有提及
2)lua的調用棧從1到N爲棧增加,即從棧底向棧頂進發。-1爲棧頂,-N爲棧底。具體的內存結構還沒看
3)QuickSort和HeapSort的確切代碼,主要在於QuickSort的非遞歸實現。非遞歸沒真正實現過了,今晚處理一下。
4)認真考究cocos2d的主線線程流程,有利於以後做架構優化


5、lua腳本調用C++,則是先壓函數地址爲0下標位;C++、lua入棧從左參數開始入棧。C++若調用lua的函數則需要使用lua_call;Lua只能調用使用特定格式的函數:
定義一個C/C++函數:  
代碼:typedef int (*lua_CFunction) (lua_State *L); //要求參數和返回值必須和這個一直,即可以賦值函數指針給lua_CFunction的都可以被調用
函數必須以Lua解釋器作爲參數,並且返回值爲int類型。既然Lua解釋器作爲函數的參數,那麼實際上函數可以從棧中取得任意多個參數。下面我 們將看到,返回的整數值代表入棧的值的數目。如果有一個C/C++函數,你想在Lua中調用他,很容易封裝一下就可以滿足上述要求。


6、上面一條成爲C++粘合層,cocos2d-lua的分支就是增加了粘合層來建立lua虛擬機和C++庫的連接,同時刪減沒必要了模塊。這個粘合層在設計模式中叫做代理,早前雲風曾經提到是否使用類似的設計,如果真要提供庫,必須減少粘合層的厚度才能保證健壯性
lua這邊的庫也要實現Lua的粘合層,才能使得腳本開發時使用的是和C++類似的API。
cocos的粘合層需要重新編寫一邊,這也是爲什麼自定義庫需要使用luabinding等工具方便。而維護引擎必須也要熟悉cocos接口設計思想,如第3條,都會根據參數個數去實現粘合調用的是哪個接口,quick引擎組要做的事情大部分是這個吧。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章