• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            LUA和C之間的函數(shù)調(diào)用



            1.1 從C程序調(diào)用LUA函數(shù)

            LUA的函數(shù)和普通變量一樣也是First Class Variable類(lèi)型,可以看作函數(shù)指針變量參與棧操作。因此調(diào)用過(guò)程分為如下幾個(gè)步驟:
            1. 請(qǐng)求LUA函數(shù)(指針)入(GLOBAL)棧。
            2. 將函數(shù)需要的參數(shù)入棧,入棧順序按照參數(shù)被聲明的順序。
            3. 告知LUA虛擬機(jī)入棧參數(shù)的個(gè)數(shù)、函數(shù)返回值的個(gè)數(shù),并調(diào)用此LUA函數(shù)。
            4. 從棧定獲得返回值,先返回的先入棧,然后將返回值顯式出棧。

            1.2 從LUA腳本調(diào)用C函數(shù)

            LUA沒(méi)有提供PYTHON那樣豐富的類(lèi)庫(kù),因此復(fù)雜的功能需要在C程序中定義好,然后通過(guò)lua決定調(diào)用時(shí)機(jī)。在LUA庫(kù)中定義了可以被LUA虛擬機(jī)識(shí)別的C函數(shù)模型:
            int functionName (lua_State* L) {....; return 1;}

            這樣的函數(shù)被是一個(gè)合法的lua_CFunction類(lèi)型,將函數(shù)注冊(cè)到LUA虛擬機(jī)中以后,就可以在LUA中以普通LUA函數(shù)的方式被調(diào)用。注冊(cè)一個(gè)C函數(shù)的步驟如下:
            1. 聲明并定義一個(gè)滿足上述模型的函數(shù) (eg. myFunInC)
            2. 用字符串為此C函數(shù)取一個(gè)名稱并入棧(eg. myFunInLua)
            3. 將函數(shù)(指針)入棧
            4. 調(diào)用LUA庫(kù)的注冊(cè)函數(shù)功能,將上述的名稱與函數(shù)指針關(guān)聯(lián)
            這樣就可以在LUA中用myFunInLua()來(lái)調(diào)用C中的int myFunInC()了

            2. 從C調(diào)用LUA函數(shù)示例

            在下面的代碼中,我們調(diào)用了LUA腳本中的fnEx2函數(shù),返回值從棧中取得,并且要手動(dòng)出棧。這里,入棧的函數(shù)參數(shù)會(huì)由pcall自動(dòng)清理。

            2.1 LUA測(cè)試腳本代碼

            function fnex2(str_a, num_b, num_c)
                print(str_a);
                return num_b
            *100 + num_c*10"Thank you";
            end;



            2.2 VC代碼

            //初始化LUA虛擬機(jī)
            void InitLuaState(lua_State* L)
            {
                
            /* Load Libraries */
                luaopen_base(L);
                luaopen_table(L);
                luaL_openlibs(L);
                luaopen_string(L);
                luaopen_math(L);
            }


            int call_lua_function(void)
            {
                
            const char* szInParam = "This is an [IN] parameter";
                
            const int iParam1 = 20, iParam2 = 50;
                cout 
            << "=================================" << endl
                     
            << "02_Call_Function" << endl
                     
            << "=================================" << endl
                     
            << "This demo calls functions in LUA scripts." << endl
                     
            << "Argument 1:" << szInParam << endl
                     
            << "Argument 2:" << iParam1 << endl
                     
            << "Argument 3:" << iParam2 << endl
                     
            << "---------------------------------" << endl
                     
            << "#OUTPUTS#" << endl;

                lua_State
            * L = lua_open();
                InitLuaState(L);

                
            int iError;

                
            /* Load Script */
                iError 
            = luaL_loadfile(L, "../test02.lua");
                
            if (iError)
                
            {
                    cout 
            << "Load script FAILED!" 
                         
            << lua_tostring(L, -1)
                         
            << endl;
                    lua_close(L);
                    
            return 1;
                }


                
            /* Run Script */
                iError 
            = lua_pcall(L, 000);
                
            if (iError)
                
            {
                    cout 
            << "pcall FAILED"
                         
            << lua_tostring(L, -1)
                         
            << iError 
                         
            << endl;
                    lua_close(L);
                    
            return 1;
                }

                
                
            /* Push a FUNCTION_VAR to STACK */
                lua_getglobal(L, 
            "fnex2");

                
            /* Push PARAMETERS to STACK */
                lua_pushstring(L, szInParam);
                lua_pushnumber(L, iParam1);
                lua_pushnumber(L, iParam2);

                
            /* Call FUNCTION in LUA */
                iError 
            = lua_pcall( L,    //VMachine
                                    3,    //Argument Count
                                    2,    //Return Value Count
                                    0 );
                
            if (iError)
                
            {
                    cout 
            << "pcall FAILED"
                         
            << lua_tostring(L, -1)
                         
            << iError 
                         
            << endl;
                    lua_close(L);
                }


                
            /* Check Return Value Types */
                
            if (lua_isstring(L, -1&& lua_isnumber(L, -2))
                
            {
                    cout 
            << "Ret_1(string): " << lua_tostring(L, -1<< endl;
                    cout 
            << "Rec_2(double): " << lua_tonumber(L, -2<< endl;
                }

                
            else
                
            {
                    cout 
            << "Wrong Return Values" << endl;
                }


                
            /* POP STACK */
                lua_pop(L,
            2);    //只需要清理Return Value,pcall調(diào)用的入棧參數(shù)會(huì)自動(dòng)清理
                lua_close(L);
                
            return 0;
            }



            2.3 工具

            下面的宏可以簡(jiǎn)化調(diào)用lua函數(shù)的代碼:
            #define CallLuaFunc(FuncName, Params, Results) 

                lua_getglobal (g_pLuaState, FuncName); 
                lua_call (g_pLuaState, Params, Results); 
            }



            3. 從LUA調(diào)用C函數(shù)示例

            在下面的例子中,我們注冊(cè)一個(gè)名為rmath的LUA函數(shù),他在C中的函數(shù)名為RMath_LUA()

            3.1 LUA腳本代碼

            print (">>> LUA程序開(kāi)始運(yùn)行了 ");

            function fnex3(num_a, num_b)
                
            local c = rmath(num_a, num_b);
                print(
            "LUA PRINTTING:", c);
                return c;
            end;



            3.2 VC程序代碼

            //LUA腳本調(diào)用C函數(shù)
            int call_c_function(void)
            {
                
            int iArg1 = 3, iArg2 = 10, iError;
                cout 
            << "=================================" << endl
                     
            << "下面的程序演示從LUA腳本中調(diào)用C函數(shù)" << endl
                     
            << "Argument 1:" << iArg1 << endl
                     
            << "Argument 2:" << iArg2 << endl
                     
            << "---------------------------------" << endl
                     
            << "#OUTPUTS#" << endl;
                lua_State
            * L = lua_open();
                InitLuaState(L);

                iError 
            = luaL_loadfile(L, "../test03.lua");
                
            if (iError) cout << "載入腳本失敗" << endl;

                iError 
            = lua_pcall(L, 000);
                
            if (iError) cout << "執(zhí)行LUA腳本失敗" << endl;

                
            /* 將C函數(shù)(指針)壓棧 */
                lua_pushstring(L, 
            "rmath");
                lua_pushcfunction(L, RMath_LUA);
                lua_settable(L, LUA_GLOBALSINDEX);

                
            /* LUA函數(shù)也是變量(指針),可以壓入棧 */
                lua_getglobal(L, 
            "fnex3");

                
            /* 將提供給LUA函數(shù)的參數(shù)入棧 */
                lua_pushnumber(L, iArg1);
                lua_pushnumber(L, iArg2);

                
            /* 調(diào)用LUA函數(shù)(pcall函數(shù)會(huì)自動(dòng)清除入棧的變量) */
                
            int Error = lua_pcall(  L,        //虛擬機(jī)指針
                                        2,        //2個(gè)參數(shù)
                                        1,        //1個(gè)返回值
                                        0 );

                
            if (Error) cout << "pcall調(diào)用fnex3函數(shù)失敗" << endl;

                
            /* 檢驗(yàn)返回值類(lèi)型 */
                
            if (lua_isnumber(L, -1))
                
            {
                    cout 
            << "有1個(gè)(double)返回值 = "
                         
            << lua_tonumber(L, -1)
                         
            << endl;
                }


                
            /* 將LUA函數(shù)返回值出棧 */
                lua_pop(L, 
            1);
                lua_close(L);
                
            return 0;
            }


            //可供LUA調(diào)用的C函數(shù)原型
            int RMath_LUA(lua_State* L)
            {
                
            if (!lua_isnumber(L, 1))
                
            {
                    lua_pushstring(L, 
            "Arg_1不是數(shù)字");
                    lua_error(L);
                }


                
            if (!lua_isnumber(L, 2))
                
            {
                    lua_pushstring(L, 
            "Arg_2不是數(shù)字");
                    lua_error(L);
                }


                
            /* GET ARGUMENT FROM STACK */
                
            double a = lua_tonumber(L, 1); 
                
            double b = lua_tonumber(L, 2);

                
            /* PUSH RESULT TO STACK */
                lua_pushnumber(L, a 
            * b);

                
            /* COUNT OF RETURN VARS*/
                
            return 1;
            }



            4. 程序解釋

            4.1 調(diào)用LUA腳本中的函數(shù)

            調(diào)用LUA腳本函數(shù)主要用到如下幾個(gè)LUA庫(kù)函數(shù):
                /* Push a FUNCTION_VAR to STACK */
                lua_getglobal(L, 
            "fnex2");

                
            /* Push PARAMETERS to STACK */
                lua_pushstring(L, szInParam);
                lua_pushnumber(L, iParam1);
                lua_pushnumber(L, iParam2);

                
            /* Call FUNCTION in LUA */
                iError 
            = lua_pcall( L,3,2,0);


            通過(guò)lua_getglobal請(qǐng)求函數(shù)(指針)入棧,然后將函數(shù)參數(shù)按聲明順序入棧,調(diào)用lua_pcall執(zhí)行函數(shù)。lua_pcall的第一個(gè)參數(shù) 指向LUA虛擬機(jī),第二個(gè)參數(shù)表示棧頂有多少個(gè)函數(shù)參數(shù),第三個(gè)參數(shù)表示此函數(shù)將返回幾個(gè)值。(pcall自動(dòng)清理入棧的參數(shù),返回值則需要手動(dòng) pop。)

            4.2 從LUA調(diào)用C函數(shù)

            主要用到如下幾個(gè)函數(shù),為求方便您也可以自己定義這樣的一個(gè)宏。
                lua_pushstring(L, "rmath");
                lua_pushcfunction(L, RMath_LUA);
                lua_settable(L, LUA_GLOBALSINDEX);

            • 函數(shù)名入棧
            • lua_CFunction類(lèi)型的函數(shù)指針入棧
            • 調(diào)用lua_settable注冊(cè)函數(shù)
            這樣就可以在lua腳本中調(diào)用rmath()函數(shù)了。

            posted on 2009-01-04 13:43 RedLight 閱讀(9315) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): RPG游戲邏輯設(shè)計(jì)

            <2008年4月>
            303112345
            6789101112
            13141516171819
            20212223242526
            27282930123
            45678910

            導(dǎo)航

            統(tǒng)計(jì)

            公告


            Name: Galen
            QQ: 88104725

            常用鏈接

            留言簿(3)

            隨筆分類(lèi)

            隨筆檔案

            相冊(cè)

            My Friend

            搜索

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            久久精品国产半推半就| 亚洲中文精品久久久久久不卡| 亚洲精品国精品久久99热一| 久久精品视频一| 久久久久高潮毛片免费全部播放| 久久亚洲美女精品国产精品| 好属妞这里只有精品久久| 99久久精品日本一区二区免费| 久久综合丁香激情久久| 亚洲美日韩Av中文字幕无码久久久妻妇| 欧美国产成人久久精品| 99久久免费只有精品国产| 久久久久亚洲AV成人网人人网站| 国产∨亚洲V天堂无码久久久| 久久久亚洲精品蜜桃臀| 久久精品夜夜夜夜夜久久| 国产午夜福利精品久久| 久久久一本精品99久久精品66 | 久久亚洲精品国产精品| 99久久精品国产一区二区蜜芽| 亚洲中文字幕无码一久久区| 激情久久久久久久久久| 久久99精品久久久久子伦| 亚洲欧美久久久久9999| 国产毛片久久久久久国产毛片 | 久久无码AV中文出轨人妻| 久久久久亚洲av无码专区喷水| 一本久久精品一区二区| 国产精品99久久久久久董美香| 久久久久99精品成人片试看| 久久久久人妻一区二区三区| 亚洲国产精品无码久久青草| 国产精品内射久久久久欢欢| 99久久婷婷国产一区二区| 久久精品国产99久久久| 麻豆一区二区99久久久久| 无码日韩人妻精品久久蜜桃 | 久久精品国产免费观看| 久久精品卫校国产小美女| 久久久久久久久久久| 日韩av无码久久精品免费|