青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

posts - 12,  comments - 6,  trackbacks - 0
這幾天搞了一個(gè)套lua與C++相互調(diào)用的框架,是之前單位項(xiàng)目中提取出來的,比較成型,在已上線的端游中使用,使用第三方庫(kù)tolua。
這里使用lua 5.1.5、tolua++ 1.0.92、boost 1.68.0、zlib。
開發(fā)環(huán)境:vs 2017 、lua調(diào)試插件 BabeLua。
lua-5.1.5.zip
toluapp-master.zip
BabeLua-For-2017-V3.2.2.0.zip
先貼圖,介紹一下工程目錄。

lua項(xiàng)目;lua代碼 —— 編譯lua.lib
tolua項(xiàng)目:tolua++代碼 —— 編譯 tolua.lib 和 tolua.exe
LuaProject項(xiàng)目:lua和c++相互交互工程。
LuaScript項(xiàng)目:插件BabeLua 創(chuàng)建,lua腳本編寫、調(diào)試使用。
lua項(xiàng)目 (vs2017中搭建lua5.1)
創(chuàng)建靜態(tài)鏈接庫(kù)的空工程、添加lua代碼文件。
修改工程配置如圖(竊取兩圖)
編輯生成 lua.lib
tolua項(xiàng)目
創(chuàng)建空工程、添加tolua代碼文件。
這里注意的是 tolua\src 目錄下有 bin 和 lib 路徑代碼。分別控制編譯 exe 和 lib文件。
我這里為了方便,將bin和lib代碼同時(shí)加入tolua工程。
然后控制 配置類型來生成 應(yīng)用程序(.exe) 和 靜態(tài)庫(kù)(.lib)
修改工程配置
附加包含目錄:..\include;..\..\lua\src;
附加依賴項(xiàng):lua.lib
預(yù)處理器定義:_CRT_SECURE_NO_WARNINGS
編譯生成 tolua.lib 和 tolua.exe
LuaProject項(xiàng)目
看一下工程代碼如圖
還挺多,不要慌,這里主要實(shí)現(xiàn)的讀取的文件可以是zip文件(壓縮以后的lua文件)。
主要類也就是 ScriptVmArgs類 和 ScriptVM類 來實(shí)現(xiàn)的 lua與c++ 的交互。
這里貼出代碼如下:


ScriptVmArgs.h
/*************************************************
vic.MINg        2018/09/18
***********************************************
*/

#pragma once
#include <string>
//  "boost/config/user.hpp" 取消 BOOST_ALL_NO_LIB 注釋
#define  BOOST_ALL_NO_LIB
#include "boost/tuple/tuple.hpp"



struct lua_State;

class ScriptVmArgs
{
    friend class ScriptVM;

    class Args
    {
    public:
        virtual int Size()const = 0;
    };

    class ArgsInput
        :public Args
    {
    public:
        virtual void Push(lua_State& lua)const = 0;
    };

    class ArgsOutput
        :public Args
    {
    public:
        virtual void Pop(lua_State& lua) = 0;
    };

    template<typename T>
    class ArgsInputImp
        :public ArgsInput
    {
    public:
        ArgsInputImp(const T& args) :m_args(args) {}
        virtual void Push(lua_State& lua)const
        {
            Push(lua, m_args);
        }
        virtual int Size()const
        {
            return boost::tuples::length<T>::value;
        }

    private:
        static void Push(lua_State& lua, const boost::tuples::null_type& args) {}
        template<typename Head, typename Tail>
        static void Push(lua_State& lua, const boost::tuples::cons<Head, Tail>& args)
        {
            // 這里巧妙的使用了 boost::tuple 的 args.get_head() 和  args.get_tail() 方法,兩行代碼實(shí)現(xiàn)了 自身的遞歸調(diào)用。
            DoPush(lua, args.get_head());
            Push(lua, args.get_tail());
        }

        const T& m_args;
    };

    template<typename T>
    class ArgsOutputImp
        :public ArgsOutput
    {
    public:
        ArgsOutputImp(T& args) :m_args(args) {}
        virtual void Pop(lua_State& lua)
        {
            Pop(lua, m_args, 0);
        }
        virtual int Size()const
        {
            return boost::tuples::length<T>::value;
        }

    private:
        static void Pop(lua_State& lua, const boost::tuples::null_type& args, int idx) {}
        template<typename Head, typename Tail>
        static void Pop(lua_State& lua, const boost::tuples::cons<Head, Tail>& args, int idx)
        {
            //if (args.get_head())
            DoPop(lua, args.get_head(), idx - boost::tuples::length<T>::value);
            Pop(lua, args.get_tail(), idx + 1);
        }

        T& m_args;
    };

    static void DoPush(lua_State& lua, const char* pcArg);
    static void DoPush(lua_State& lua, bool bArg);
    static void DoPush(lua_State& lua, float fArg);
    static void DoPush(lua_State& lua, int nArg);
    static void DoPush(lua_State& lua, unsigned uArg);
    static void DoPop(lua_State& lua, std::string& sArg, int idx);
    static void DoPop(lua_State& lua, bool& bArg, int idx);
    static void DoPop(lua_State& lua, float& fArg, int idx);
    static void DoPop(lua_State& lua, int& nArg, int idx);
    static void DoPop(lua_State& lua, unsigned& uArg, int idx);
};

ScriptVM.h
/*************************************************
vic.MINg        2018/09/18
***********************************************
*/

#pragma once

#include <vector>
#include <map>
#include <string>

#include "ScriptVmArgs.h"

struct lua_State;

struct lua_Debug;
typedef void(*lua_Hook) (lua_State *L, lua_Debug *ar);
typedef int(*lua_CFunction) (lua_State *L);


class ScriptVM
{
public:

    ScriptVM(void);
    virtual ~ScriptVM(void);

    bool    Init(void);
    void    Destroy(void);
    void    ExecuteScriptFile(const char * sScriptFileName, bool bForceReload = falsebool bAssertOnError = true);
    void    ExecuteScript(const char * sScript, bool bAssertOnError = true);
    bool    ExecuteScriptFunc(const std::vector<const char *>& modules, const char * func, bool bAllowNonexist, const char * sig = "", );
    template<typename InTuple, typename OutTuple>
    void ExecuteFunc(const char* func, bool bAllowNonexist, const InTuple& inTuple, OutTuple& outTuple, const std::vector<const char*>* pModuls = 0);
    void    ExposeGlobalUserdata(void * va, const char * name, const char * type);
    void *    GetGlobalUserdata(const char * name, const char * verify_type = NULL);
    void *    GetUserdata(const std::vector<const char *>& modules, const char * name, const char * verify_type = NULL);
    double    GetGlobalNumber(const char * name);
    // 是否存在某變量
    bool    ExistVariable(const std::vector<const char *>& modules, const char * name);

    // 得到某個(gè)Lua變量
    bool    GetNumber(const std::vector<const char *>& modules, const char * name, double& dValue);

    //void    OnEndofUpdate(); //call back function on end of game update
    void *    CreateObjectByTypeName(const char * sTypeName);//由tolua注冊(cè)過的類名創(chuàng)建對(duì)象
    double    GetGlobalTableNumber(const char *sTableName, const char* key);//Wang Hongliang:
    double ComputingFormula(const char* sFormula, const std::map<std::stringdouble>& kParams);// 計(jì)算數(shù)學(xué)公式
    lua_State * GetLuaState() { return m_pLua; }

    // 設(shè)置腳本鉤子,只在調(diào)試時(shí)可用。 
    void    SetHook(lua_Hook func, int nMask, int nCount);
    void    RegistGlobalFunction(const char* sFunctionName, lua_CFunction pFunction);


    // 這里通過 自己寫的io流來處理的 文件讀寫,把文件內(nèi)容讀到了buff 中 
    
// 我這里支撐壓縮文件的讀寫,你可以自己實(shí)現(xiàn)一下文件讀寫方法 重寫該方法即可
    static bool LoadFileToBuffer(const char * filename, unsigned char *& buff, int& size, bool bAssertOnError);
    std::string GetScriptReturnString(std::string sScript);
    
    
    //static sigslot::signal1<const char*> LuaPrinted;

    
// 獲取腳本當(dāng)前所占用的內(nèi)存
    int        GetConsumeMemoryCount();

    // 打印所有全局變量
    void    PrintGlobalVariables();

protected:
    void DoExecuteFunc(const char* func, bool bAllowNonexist, const  ScriptVmArgs::ArgsInput& input, ScriptVmArgs::ArgsOutput& output, const std::vector<const char*>* pModuls);

    lua_State* m_pLua;
};

template<typename InTuple, typename OutTuple>
inline void ScriptVM::ExecuteFunc(const char* func, bool bAllowNonexist, const InTuple& inTuple, OutTuple& outTuple, const std::vector<const char*>* pModuls /* = 0 */)
{
    // Pass as ArgsInput and ArgsOutput, not ArgsInputImp and ArgsOutputImp. So that the body of DoExecuteFunc() can be placed in .cpp rather than .h.
    DoExecuteFunc(
        func,
        bAllowNonexist,
        ScriptVmArgs::ArgsInputImp<InTuple>(inTuple),
        (ScriptVmArgs::ArgsOutput&)ScriptVmArgs::ArgsOutputImp<OutTuple>(outTuple),            // 為啥子 必須強(qiáng)制轉(zhuǎn)換一下 ScriptVmArgs::ArgsOutput& 上面的代碼就不用轉(zhuǎn)換,沒整明白
        pModuls
    );
}

ScriptVM.cpp
#include "ScriptVM.h"
#include "IOServer.h"
#include "FileStream.h"

extern "C"
{
    #include "lua.h"  
    #include "lualib.h"  
    #include "lauxlib.h"  
}
#include "tolua++.h"

#include<stdio.h>
#include <assert.h>
#include <sstream>

#define DEBUG_STACK 0

//end of tolua bind declare
extern void tolua_open_binding(lua_State * pLua);
static void stackDump(lua_State *pLua);

//sigslot::signal1<const char*> ScriptVM::LuaPrinted;

//error_msg handling function
static void error_msg(bool bUseAssert, const char * pacFmt, )
{
    //#if defined(_DEBUG)
    char acTemp[2048];

    va_list args;
    va_start(args, pacFmt);
    vsprintf_s(acTemp, pacFmt, args);
    va_end(args);
    if (bUseAssert)
    {
        assert( acTemp);
    }
    //#endif
}

void report_last_error(lua_State *pLua, bool bUseAssert)
{
    lua_getglobal(pLua, "_ALERT");
    error_msg(bUseAssert, "%s\n", lua_tostring(pLua, -2));
    error_msg(bUseAssert, "%s\n", lua_tostring(pLua, -1));
    lua_pop(pLua, 2);  /* remove error_msg message and _ALERT */
}


std::string & std_string_format(std::string & _str, const char * _Format, ) {
    std::string tmp;

    va_list marker = NULL;
    va_start(marker, _Format);

    size_t num_of_chars = _vscprintf(_Format, marker);

    if (num_of_chars > tmp.capacity()) {
        tmp.resize(num_of_chars + 1);
    }

    vsprintf_s((char *)tmp.data(), tmp.capacity(), _Format, marker);

    va_end(marker);

    _str = tmp.c_str();
    return _str;
}


ScriptVM::ScriptVM(void)
{
}

ScriptVM::~ScriptVM(void)
{
}

static int PrintStringList(lua_State * pLua) {

    int n = lua_gettop(pLua);  /* number of arguments */
    int i;
    lua_getglobal(pLua, "tostring");
    std::string out;
    for (i = 1; i <= n; i++) {
        const char *s;
        lua_pushvalue(pLua, -1);  /* function to be called */
        lua_pushvalue(pLua, i);   /* value to print */
        lua_call(pLua, 1, 1);
        s = lua_tostring(pLua, -1);  /* get result */
        if (s == NULL)
            return luaL_error(pLua, "`tostring' must return a string to `print'");
        if (i > 1)
        {
            out += "\t";
            out += s;
        }
        else
            out += s;

        lua_pop(pLua, 1);  /* pop result */
    }
    out += "\n";

    return 0;
}

bool ScriptVM::Init(void)
{
    m_pLua = luaL_newstate();

    lua_cpcall(m_pLua, luaopen_base, 0);
    lua_cpcall(m_pLua, luaopen_io, 0);
    lua_cpcall(m_pLua, luaopen_string, 0);
    lua_cpcall(m_pLua, luaopen_table, 0);
    lua_cpcall(m_pLua, luaopen_math, 0);
    lua_cpcall(m_pLua, luaopen_debug, 0);
    lua_cpcall(m_pLua, luaopen_os, 0);
    lua_cpcall(m_pLua, luaopen_package, 0);

    //luaopen_base(m_pLua);
    
//luaopen_io(m_pLua);
    
//luaopen_table(m_pLua);
    
//luaopen_math(m_pLua);
    
//luaopen_string(m_pLua);
    
//luaopen_debug(m_pLua);

    
//tolua_open_binding(m_pLua);

    
//lua_setgcthreshold(m_pLua, 200); //200k garbage collection threshold
    lua_register(m_pLua, "print", PrintStringList);
    //lua_register(m_pLua, "dofile", OverrideDofile);

    return true;
}

void ScriptVM::Destroy(void)
{
    lua_close(m_pLua);
}

void ScriptVM::ExecuteScriptFile(const char * sScriptName, bool bForceReload /* = false*/bool bAssertOnError /*= true*/)
{
    int nSize1 = lua_gettop(m_pLua);
    //get chunk name as modified script name
    std::string sChunkName(sScriptName);
    for (unsigned int i = 0; i < sChunkName.length(); i++)
    {
        if (sChunkName[i] == '/' || sChunkName[i] == '.')
            sChunkName[i] = '_';
    }

    //get the chunk global
    lua_getglobal(m_pLua, sChunkName.c_str());
    if (bForceReload || !lua_isfunction(m_pLua, -1))//if force reload or not found
    {
        //load it first
        unsigned char * pBuff;
        int nSize;
        if (LoadFileToBuffer(sScriptName, pBuff, nSize, bAssertOnError))
        {
            luaL_loadbuffer(m_pLua, (char *)pBuff, nSize, sScriptName);

            delete[] pBuff;

//            luaL_loadfile(m_pLua, sScriptName);
            lua_setglobal(m_pLua, sChunkName.c_str());
            lua_getglobal(m_pLua, sChunkName.c_str());
        }
        else
            goto failed;
    }

    if (lua_pcall(m_pLua, 0, 0, 0) != 0)
    {
        error_msg(bAssertOnError, "error executing script file %s: ", sScriptName);
        report_last_error(m_pLua, bAssertOnError);
    }

failed:
    lua_settop(m_pLua, nSize1);
}

void ScriptVM::ExecuteScript(const char * sScript, bool bAssertOnError)
{
    int status = luaL_loadbuffer(m_pLua, sScript, strlen(sScript), sScript);
    if (status)
    {
        report_last_error(m_pLua, bAssertOnError);
    }
    else
    {
        status = lua_pcall(m_pLua, 0, LUA_MULTRET, 0);  /* call main */
        if (status)
            report_last_error(m_pLua, bAssertOnError);
    }
}

/*
*    Execute Script Function func in the script. copy/pasted from the book "programming in LUA"
*/
bool ScriptVM::ExecuteScriptFunc(const std::vector<const char *>&modules, const char * func, bool bAllowNonexist, const char * sig, )
{
    bool bIsSuccess = false;

    //PROFILE("ExecuteScriptFunc");
    int nSize1 = lua_gettop(m_pLua);

    //debug
#if DEBUG_STACK
    printf("debug lua: stack size before ExecuteScriptFunc = %d\n", nSize1);
#endif

    va_list    vl;
    int    narg, nres;    /* number of arguments and results */
    va_start(vl, sig);

    //get the actual function
    if (modules.empty()) //func is global
    {
        lua_getglobal(m_pLua, func);
        if (!lua_isfunction(m_pLua, -1))
        {
            if (!bAllowNonexist)
                error_msg(true, "ExecuteScriptFunc: Invalid function name: %s\n", func);
            goto failed;
        }
    }
    else
    {
        //trace down the modules
        std::vector<const char *>::const_iterator it = modules.begin();
        //get the global module name or the actual function name if there is no module
        lua_getglobal(m_pLua, *it);
        if (!lua_istable(m_pLua, -1))
        {
            if (!bAllowNonexist)
                error_msg(true, "ExecuteScriptFunc: Invalid table name: %s\n", *it);
            goto failed;
        }

        for (++it; it != modules.end(); ++it)
        {
            lua_pushstring(m_pLua, *it);
            lua_gettable(m_pLua, -2);
            if (!lua_istable(m_pLua, -1))
            {
                if (!bAllowNonexist)
                    error_msg(true, "ExecuteScriptFunc: Invalid table name: %s\n", *it);
                goto failed;
            }
        }
        //get the func
        lua_pushstring(m_pLua, func);
        lua_gettable(m_pLua, -2);
        if (!lua_isfunction(m_pLua, -1))
        {
            if (!bAllowNonexist)
                error_msg(true, "ExecuteScriptFunc: Invalid function name: %s\n", func);
            goto failed;
        }
    }

    /* push    arguments */
    narg = 0;
    while (*sig) { /* push arguments    */
        switch (*sig++) {
        case 'd': /* double    argument */
        case 'f': /* float    argument */    // NieXu: Treat float as double, same as printf()
            lua_pushnumber(m_pLua, va_arg(vl, double));
            break;
        case 'i': /* int argument */
            lua_pushnumber(m_pLua, va_arg(vl, int));
            break;
        case 's': /* string    argument */
            lua_pushstring(m_pLua, va_arg(vl, char *));
            break;
        case 'b': /* boolean argument */
            lua_pushboolean(m_pLua, va_arg(vl, bool));
            break;
        case 'u': /* light user data */
            lua_pushlightuserdata(m_pLua, va_arg(vl, void *));
            break;
        case 't': /* type user data */
        {
            void* pData = va_arg(vl, void *);
            const char* sType = va_arg(vl, const char*);
            tolua_pushusertype(m_pLua, pData, sType);
            break;
        }

        case '>':
            goto endwhile;
        default:
            error_msg(true, "invalid option (%c)\n", *(sig - 1));
            goto failed;
        }
        narg++;
        luaL_checkstack(m_pLua, 1, "too many    arguments");
    }endwhile:
    /* do the call */
    nres = strlen(sig);    /* number of expected results */
    if (lua_pcall(m_pLua, narg, nres, 0) != 0) /* do    the    call */
    {
        report_last_error(m_pLua, true);
        goto failed;
    }
    /* retrieve    results    */
    nres = -nres; /* stack index of    first result */
    while (*sig)
    { /* get results */
        switch (*sig++)
        {
        case 'd': /* double    result */
            if (!lua_isnumber(m_pLua, nres))
                error_msg(true, "wrong    result type,function name: %s\n", func);
            *va_arg(vl, double *) = lua_tonumber(m_pLua, nres);
            break;
        case 'f': /* float    result */
            if (!lua_isnumber(m_pLua, nres))
                error_msg(true, "wrong    result type,function name: %s\n", func);
            *va_arg(vl, float*) = (float)lua_tonumber(m_pLua, nres);
            break;
        case 'i': /* int result    */
            if (!lua_isnumber(m_pLua, nres))
                error_msg(true, "wrong    result type,function name: %s\n", func);
            *va_arg(vl, int    *) = (int)lua_tonumber(m_pLua, nres);
            break;
        case 's': /* string    result */
            if (!lua_isstring(m_pLua, nres))
                error_msg(true, "wrong    result type,function name: %s\n", func);
            *va_arg(vl, std::string*) = lua_tostring(m_pLua, nres);
            break;
        case 'b': /* boolean argument */
            if (!lua_isboolean(m_pLua, nres))
                error_msg(true, "wrong    result type,function name: %s\n", func);
            *va_arg(vl, bool *) = (0 != lua_toboolean(m_pLua, nres));
            break;
        case 'u': /* light user data */
            if (!lua_isuserdata(m_pLua, nres))
                error_msg(true, "wrong    result type,function name: %s\n", func);
            *va_arg(vl, void **) = lua_touserdata(m_pLua, nres);
            break;
        default:
            error_msg(true, "invalid option (%c)\n", *(sig - 1));
        }
        nres++;
    }

    bIsSuccess = true;
failed:
    va_end(vl);
    //clear the stack
    lua_settop(m_pLua, nSize1);

#if DEBUG_STACK
    //debug
    int nSize2 = lua_gettop(m_pLua);
    printf("debug lua: stack size after ExecuteScriptFunc = %d\n", nSize2);
    if (nSize1 != nSize2)
        stackDump(m_pLua);
#endif

    return bIsSuccess;
}

void ScriptVM::ExposeGlobalUserdata(void * va, const char * name, const char * type)
{
    int nSize1 = lua_gettop(m_pLua);
#if DEBUG_STACK
    //debug
    printf("debug lua: stack size before ExposeGlobalUserdata = %d\n", nSize1);
#endif

    tolua_pushusertype(m_pLua, va, type);
    lua_setglobal(m_pLua, name);

    //clear the stack
    lua_settop(m_pLua, nSize1);

#if DEBUG_STACK
    //debug
    int nSize2 = lua_gettop(m_pLua);
    printf("debug lua: stack size after ExposeGlobalUserdata = %d\n", nSize2);
    if (nSize1 != nSize2)
        stackDump(m_pLua);
#endif
}

void * ScriptVM::GetGlobalUserdata(const char * name, const char * verify_type /*= NULL*/)
{
    void * pRet = NULL;
    int nSize1 = lua_gettop(m_pLua);
    int nSize2 = 0;
#if DEBUG_STACK
    //debug
    printf("debug lua: stack size before GetGlobalUserdata = %d\n", nSize1);
#endif

    lua_getglobal(m_pLua, name);

    //verify type
    if (verify_type)
    {
        tolua_Error tolua_err;
        if (
            !tolua_isusertype(m_pLua, 1, verify_type, 0, &tolua_err) ||
            !tolua_isnoobj(m_pLua, 2, &tolua_err)
            )
        {
            tolua_error(m_pLua, "#ferror in function 'ScriptVM::GetGlobalUserdata'.", &tolua_err);
            goto failed;
        }
    }
    
         pRet = tolua_tousertype(m_pLua, -1, 0);
        //clear the stack
        lua_settop(m_pLua, nSize1);




#if DEBUG_STACK
    //debug
    nSize2 = lua_gettop(m_pLua);
    printf("debug lua: stack size after GetGlobalUserdata = %d\n", nSize2);
    if (nSize1 != nSize2)
        stackDump(m_pLua);
#endif
    return pRet;

failed:
        //lua_settop(m_pLua,0);
        lua_settop(m_pLua, nSize1);
        return NULL;

}

double ScriptVM::GetGlobalNumber(const char * name)
{
    int nSize1 = lua_gettop(m_pLua);
#if DEBUG_STACK
    //debug
    printf("debug lua: stack size before GetGlobalUserdata = %d\n", nSize1);
#endif

    lua_getglobal(m_pLua, name);

    double ret = tolua_tonumber(m_pLua, -1, 0);
    //clear the stack
    lua_settop(m_pLua, nSize1);

#if DEBUG_STACK
    //debug
    int nSize2 = lua_gettop(m_pLua);
    printf("debug lua: stack size after GetGlobalUserdata = %d\n", nSize2);
    if (nSize1 != nSize2)
        stackDump(m_pLua);
#endif
    return ret;
}

void * ScriptVM::GetUserdata(const std::vector<const char *>& modules, const char * name, const char * verify_type/*= NULL*/)
{
    void * pRet = NULL;
    int nSize1 = lua_gettop(m_pLua);
    int nSize2 = 0;
#if DEBUG_STACK
    printf("debug lua: stack size before GetUserdata = %d\n", nSize1);
#endif
    if (modules.empty()) //userdata is global
    {
        lua_getglobal(m_pLua, name);
    }
    else
    {
        //trace down the modules
        std::vector<const char *>::const_iterator it = modules.begin();
        //get the global module name or the actual function name if there is no module
        lua_getglobal(m_pLua, *it);
        if (!lua_istable(m_pLua, -1))
        {
            error_msg(true, "GetUserdata: Invalid table name: %s\n", *it);
            goto failed;
        }

        for (++it; it != modules.end(); ++it)
        {
            lua_pushstring(m_pLua, *it);
            lua_gettable(m_pLua, -2);
            if (!lua_istable(m_pLua, -1))
            {
                std::vector<const char *>::const_iterator itMsg = modules.begin();
                std::string sMsg;
                for (; itMsg <= it; ++itMsg)
                {
                    sMsg.append(*itMsg);
                    if (itMsg != it)
                    {
                        sMsg.append(".");
                    }
                }
                error_msg(true, "GetUserdata: Invalid table name: %s\n", sMsg.c_str());
                goto failed;
            }
        }
        //get the data
        lua_pushstring(m_pLua, name);
        lua_gettable(m_pLua, -2);
    }

    //verify type
    
//if(verify_type)
    
//{
    
//    tolua_Error tolua_err;
    
//    if (
    
//        !tolua_isusertype(m_pLua,1,verify_type,0,&tolua_err) ||
    
//        !tolua_isnoobj(m_pLua,2,&tolua_err)
    
//        )
    
//    {
    
//        error_msg(m_pLua,"#ferror in function 'ScriptVM:GetUserdata: %s\n", name);
    
//        goto failed;
    
//    }
    
//}

    pRet = tolua_tousertype(m_pLua, -1, 0);
    //clear the stack
    lua_settop(m_pLua, nSize1);

#if DEBUG_STACK
    //debug
    nSize2 = lua_gettop(m_pLua);
    printf("debug lua: stack size after GetUserdata = %d\n", nSize2);
    if (nSize1 != nSize2)
        stackDump(m_pLua);
#endif
    return pRet;

failed:
    lua_settop(m_pLua, nSize1);
    return NULL;
}

static void stackDump(lua_State *m_pLua) {
    int i;
    int top = lua_gettop(m_pLua);
    for (i = 1; i <= top; i++) { /* repeat for each level */
        int t = lua_type(m_pLua, i);
        switch (t) {
        case LUA_TSTRING: /* strings */
            printf("`%s'", lua_tostring(m_pLua, i));
            break;
        case LUA_TBOOLEAN: /* booleans */
            printf(lua_toboolean(m_pLua, i) ? "true" : "false");
            break;
        case LUA_TNUMBER: /* numbers */
            printf("%g", lua_tonumber(m_pLua, i));
            break;
        default/* other values */
            printf("%s", lua_typename(m_pLua, t));
            break;
        }
        printf(" "); /* put a separator */
    }
    printf("\n"); /* end the listing */
}

bool ScriptVM::LoadFileToBuffer(const char * filename, unsigned char *& buff, int& size, bool bAssertOnError)
{
    IO::Stream* pStream = IO::IOServer::Instance()->CreateReadStream(filename);
    if (pStream != NULL && pStream->Open())
    {
        size = pStream->GetSize();
        if (size == 0)
        {
            std::string sMsg;
            sMsg.append(filename).append("以上文件中無內(nèi)容!");
            assert( sMsg.c_str());
        }

        buff = new unsigned char[size];
        pStream->Read(buff, size);

        pStream->Close();

        IO::IOServer::Instance()->ReleaseStream(pStream);

        return true;
    }
    else
    {
        std::string sMsg;
        sMsg.append("[").append(filename).append("]腳本文件不存在!");
        assert( sMsg.c_str());

        if (NULL != pStream)
        {
            IO::IOServer::Instance()->ReleaseStream(pStream);
        }
        return false;
    }
}

//由tolua注冊(cè)過的類名創(chuàng)建對(duì)象
void *    ScriptVM::CreateObjectByTypeName(const char * sTypeName)
{
    //處理lua腳本
    int nSize = (int)strlen(sTypeName) + 20;
    unsigned char* buffer = new unsigned char[nSize];
    sprintf_s((char*)buffer, nSize, "pMyCreatedObj=%s:new()", sTypeName);

    //執(zhí)行腳本
    ExecuteScript((char*)buffer);

    void* ret = GetGlobalUserdata("pMyCreatedObj");

    return ret;
}

//獲得全局表中常量
double ScriptVM::GetGlobalTableNumber(const char *sTableName, const char* key)
{
    double ret = 0;
    int nSize1 = lua_gettop(m_pLua);
    int nSize2 = 0;
#if DEBUG_STACK
    //debug
    printf("debug lua: stack size before GetGlobalUserdata = %d\n", nSize1);
#endif
    lua_getglobal(m_pLua, sTableName);
    if (!lua_istable(m_pLua, -1))
    {
        error_msg(true, "GetGlobalTableNumber: %s isn't a Lua Table.", sTableName);
        goto failed;
    }

    lua_pushstring(m_pLua, key);
    lua_gettable(m_pLua, -2);
    if (!lua_isnumber(m_pLua, -1))
    {
        error_msg(true, "GetGlobalTableNumber: %s isn't a number.", key);
        goto failed;
    }
    ret = lua_tonumber(m_pLua, -1);
    lua_settop(m_pLua, nSize1);
#if DEBUG_STACK
    //debug
    nSize2 = lua_gettop(m_pLua);
    printf("debug lua: stack size after GetUserdata = %d\n", nSize2);
    if (nSize1 != nSize2)
        stackDump(m_pLua);
#endif

    return ret;

failed:
    lua_settop(m_pLua, nSize1);
    return 0;
}

void ScriptVM::SetHook(lua_Hook func, int nMask, int nCount)
{
    if (!m_pLua)
        return;

    //lua_sethook(m_pLua, func, nMask, nCount);
}

bool ScriptVM::ExistVariable(const std::vector<const char *>& modules, const char * name)
{
    int nSize1 = lua_gettop(m_pLua);

    if (modules.empty()) //userdata is global
    {
        lua_getglobal(m_pLua, name);
    }
    else
    {
        //trace down the modules
        std::vector<const char *>::const_iterator it = modules.begin();
        //get the global module name or the actual function name if there is no module
        lua_getglobal(m_pLua, *it);
        if (!lua_istable(m_pLua, -1))
        {
            error_msg(true, "GetUserdata: Invalid table name: %s\n", *it);
            goto failed;
        }

        for (++it; it != modules.end(); ++it)
        {
            lua_pushstring(m_pLua, *it);
            lua_gettable(m_pLua, -2);
            if (!lua_istable(m_pLua, -1))
            {
                error_msg(true, "GetUserdata: Invalid table name: %s\n", *it);
                goto failed;
            }
        }
        //get the data
        lua_pushstring(m_pLua, name);
        lua_gettable(m_pLua, -2);
    }

    if (lua_isnil(m_pLua, -1))
    {
        goto failed;
    }
    else
    {
        goto success;
    }

failed:
    lua_settop(m_pLua, nSize1);
    return false;

success:
    lua_settop(m_pLua, nSize1);
    return true;
}

// 替換字符串
void string_replace(std::string &strBig, const std::string &strsrc, const std::string &strdst)
{
    std::string::size_type pos = 0;
    std::string::size_type srclen = strsrc.size();
    std::string::size_type dstlen = strdst.size();

    while ((pos = strBig.find(strsrc, pos)) != std::string::npos)
    {
        strBig.replace(pos, srclen, strdst);
        pos += dstlen;
    }
}

double ScriptVM::ComputingFormula(const char* sFormula, const std::map<std::stringdouble>& kParams)
{
    std::string sRealFormula = sFormula;
    if (sRealFormula == "")
    {
        assert(false && "公式錯(cuò)誤");
        return 0.0;
    }

    std::string sParamValue = "0";
    std::stringstream kStrStream;

    // 替換參數(shù)
    for (std::map<std::stringdouble>::const_iterator it(kParams.begin()); it != kParams.end(); it++)
    {// 得到公式
     
//         kStrStream<<it->second;    
     
//         sParamValue = kStrStream.str();
        sParamValue = std_string_format(sParamValue, "%f", it->second);
        string_replace(sRealFormula, it->first, sParamValue);

        /*
        // 支持在公式中包含的腳本函數(shù)調(diào)用可以有字符串參數(shù),避免以當(dāng)前屬性名為字符串的參數(shù)被屬性值替換 [2/18/2011 shuaiwang]
        if (sRealFormula.find('\'') != 0xffffffff)
        {
            std::string sProParam = std::string("\'").append(it->first).append("\'");
            sRealFormula.replace(sProParam, "????");
            sRealFormula.replace(it->first, sParamValue);
            sProParam = std::string("\"").append(it->first).append("\"");
            sRealFormula.replace("????", sProParam);
        }
        else
        {
            sRealFormula.replace(it->first, sParamValue);
        }
        
*/
        
//sRealFormula.Replace(it->first, sParamValue);
    }

    std::string sReturn = "return ";

    if (sRealFormula.find(sReturn) == std::string::npos)
    {
        sRealFormula = sReturn.append(sRealFormula);
    }

    /*std::stringstream kFunStream;

    kFunStream<<"computing_formula_teamfunction = function()\n"
    << sRealFormula << "\n"
    << "end";
*/

    std::string sTempFunction = std::string("computing_formula_teamfunction = function()\n").append(sRealFormula).append("\nend")/*kFunStream.str()*/;

    ExecuteScript(sTempFunction.c_str(), true);

    std::vector<const char *> modules;
    double dValue = 0.0;
    if (ExecuteScriptFunc(modules, "computing_formula_teamfunction", false, ">d", &dValue) == false)
    {
        //_logError2("computing_formula_teamfunction這個(gè)問題的來源是:", sFormula << ",請(qǐng)?jiān)跀?shù)據(jù)表中修改相應(yīng)公式!");
    }

    ExecuteScript("computing_formula_teamfunction = nil", true);

    return dValue;
}

std::string ScriptVM::GetScriptReturnString(std::string sScript)
{
    std::string sReturn = "return ";

    if (sScript.find(sReturn) == 0xffffffff)
    {
        sScript = sReturn.append("\"").append(sScript).append("\"");
    }

    std::string sTempFunction = std::string("string_function = function()\n").append(sScript).append("\nend");
    ExecuteScript(sTempFunction.c_str(), true);

    std::vector<const char *> modules;
    std::string sReturnString;
    ExecuteScriptFunc(modules, "string_function", false, ">s", &sReturnString);

    ExecuteScript("string_function = nil", true);
    return sReturnString.c_str();
}

void ScriptVM::RegistGlobalFunction(const char* sFunctionName, lua_CFunction pFunction)
{
    lua_register(m_pLua, sFunctionName, pFunction);
}

bool ScriptVM::GetNumber(const std::vector<const char *>& modules, const char * name, double& dValue)
{
    int nSize1 = lua_gettop(m_pLua);

    if (modules.empty()) //userdata is global
    {
        lua_getglobal(m_pLua, name);
    }
    else
    {
        //trace down the modules
        std::vector<const char *>::const_iterator it = modules.begin();
        //get the global module name or the actual function name if there is no module
        lua_getglobal(m_pLua, *it);
        if (!lua_istable(m_pLua, -1))
        {
            error_msg(true, "GetUserdata: Invalid table name: %s\n", *it);
            lua_settop(m_pLua, nSize1);
            return false;
        }

        for (++it; it != modules.end(); ++it)
        {
            lua_pushstring(m_pLua, *it);
            lua_gettable(m_pLua, -2);
            if (!lua_istable(m_pLua, -1))
            {
                error_msg(true, "GetUserdata: Invalid table name: %s\n", *it);
                lua_settop(m_pLua, nSize1);
                return false;
            }
        }
        //get the data
        lua_pushstring(m_pLua, name);
        lua_gettable(m_pLua, -2);
    }

    if (lua_isnumber(m_pLua, -1))
    {
        dValue = tolua_tonumber(m_pLua, -1, 0);
        lua_settop(m_pLua, nSize1);
        return true;
    }
    else
    {
        lua_settop(m_pLua, nSize1);
        return false;
    }
}

void ScriptVM::DoExecuteFunc(const char* func, bool bAllowNonexist, const ScriptVmArgs::ArgsInput& input, ScriptVmArgs::ArgsOutput& output, const std::vector<const char*>* pModuls)
{

    //get the actual function
    const int nOrgSize = lua_gettop(m_pLua);
    int nInputSize = input.Size();
    int nOutputSize = output.Size();

    if (!pModuls || (pModuls && pModuls->empty())) //func is global
    {
        lua_getglobal(m_pLua, func);
        if (!lua_isfunction(m_pLua, -1))
        {
            if (!bAllowNonexist)
                error_msg(true, "ExecuteScriptFunc: Invalid function name: %s\n", func);
            goto failed;
        }
    }
    else
    {
        //trace down the modules
        std::vector<const char *>::const_iterator it = pModuls->begin();
        //get the global module name or the actual function name if there is no module
        lua_getglobal(m_pLua, *it);
        if (!lua_istable(m_pLua, -1))
        {
            if (!bAllowNonexist)
                error_msg(true, "ExecuteScriptFunc: Invalid table name: %s\n", *it);
            goto failed;
        }

        for (++it; it != pModuls->end(); ++it)
        {
            lua_pushstring(m_pLua, *it);
            lua_gettable(m_pLua, -2);
            if (!lua_istable(m_pLua, -1))
            {
                if (!bAllowNonexist)
                    error_msg(true, "ExecuteScriptFunc: Invalid table name: %s\n", *it);
                goto failed;
            }
        }

        //get the func
        lua_pushstring(m_pLua, func);
        lua_gettable(m_pLua, -2);
        if (!lua_isfunction(m_pLua, -1))
        {
            if (!bAllowNonexist)
                error_msg(true, "ExecuteScriptFunc: Invalid function name: %s\n", func);
            goto failed;
        }
    }

    /* push    arguments */
    input.Push(*m_pLua);

    /* do the call */
    if (lua_pcall(m_pLua, nInputSize, nOutputSize, 0) != 0) /* do    the    call */
    {
        report_last_error(m_pLua, true);
        goto failed;
    }

    /* retrieve    results    */
    output.Pop(*m_pLua);

failed:
    //clear the stack
    lua_settop(m_pLua, nOrgSize);
}

int ScriptVM::GetConsumeMemoryCount()
{
    int nCount = 0;
    if (m_pLua)
    {
        nCount = lua_getgccount(m_pLua);
    }

    return nCount;
}

void ScriptVM::PrintGlobalVariables()
{
    ExecuteScript("for n in pairs(_G) do print(n) end", true);
}

void ScriptVmArgs::DoPush(lua_State& lua, const char* pcArg)
{
    lua_pushstring(&lua, pcArg);
}

void ScriptVmArgs::DoPush(lua_State& lua, const bool bArg)
{
    lua_pushboolean(&lua, bArg);
}

void ScriptVmArgs::DoPush(lua_State& lua, const float fArg)
{
    lua_pushnumber(&lua, fArg);
}

void ScriptVmArgs::DoPush(lua_State& lua, const int nArg)
{
    lua_pushnumber(&lua, nArg);
}

void ScriptVmArgs::DoPush(lua_State& lua, unsigned uArg)
{
    lua_pushinteger(&lua, uArg);
}

void ScriptVmArgs::DoPop(lua_State& lua, bool& bArg, int idx)
{
    bArg = lua_toboolean(&lua, idx) != 0;
}

void ScriptVmArgs::DoPop(lua_State& lua, std::string& sArg, int idx)
{
    sArg = lua_tostring(&lua, idx);
}

void ScriptVmArgs::DoPop(lua_State& lua, float& fArg, int idx)
{
    fArg = (float)lua_tonumber(&lua, idx);
}

void ScriptVmArgs::DoPop(lua_State& lua, int& nArg, int idx)
{
    nArg = (int)lua_tonumber(&lua, idx);
}

void ScriptVmArgs::DoPop(lua_State& lua, unsigned& uArg, int idx)
{
    uArg = lua_tointeger(&lua, idx);
}


OK,下面來實(shí)現(xiàn)一下測(cè)試代碼,來看看如何 lua 和 c++進(jìn)行交互的。


我們來簡(jiǎn)單編寫幾個(gè)文件。

函數(shù)調(diào)用:
ScriptFunction.h
/**************************************************************************************
        vic.MINg            2018/09/19
**************************************************************************************
*/

#pragma once

namespace Script {
    //tolua_begin
    void show_luaproject_info();
    //tolua_end
}

ScriptFunction.cpp
#include "ScriptFunction.h"
#include <stdio.h>

namespace Script {

    void show_luaproject_info()
    {
        printf("Show LuaProject C++ Info.\n");
    }

}

結(jié)構(gòu)體
Hag.h
/***********************************************************************
        vic. MINg        2018/09/25
**********************************************************************
*/

#pragma once
#include <string>

//tolua_begin
struct Hag        
{
    int            hag_id;
    std::string hag_name;
    bool             is_valid;
    int            hag_score;

    Hag() { }
    virtual ~Hag() {}
};
//tolua_end


Student.h
#pragma once

#include<iostream>
using namespace std;

//tolua_begin
class Student
{
public:

    Student();
    virtual ~Student();

    void Run();
    void Run(int a);
    
};
//tolua_end

Student.cpp
#include "Student.h"


Student::Student()
{
}

void Student::Run()
{
    //cout << "Student Run" << endl;
    printf("Student Student Run.\n");
}

void Student::Run(int a)
{
    //cout << "Student Run" <<a<< endl;
    printf("Student Student Run with %d.\n", a);
}

Student::~Student()
{
}

非常簡(jiǎn)單的測(cè)試代碼。不言語。繼續(xù)往下。
我們需要編寫一份 LuaScript.pkg 文件來導(dǎo)出這些文件,讓lua可以調(diào)用他們。

LuaScript.pkg
#include "tolua++.h"

$#pragma warning(disable : 4800) //forcing value to bool warning


// script functions
$cfile "ScriptFunction.h"
$using namespace Script;


// class
$cfile "Hag.h"
$cfile "Student.h"

做一個(gè)實(shí)行腳本 glue.bat 來通過 LuaScript.pkg 編譯 lua 的cpp文件。

glue.bat
..\..\Debug\tolua -o l_LuaScript.cpp LuaScript.pkg
pause

這樣會(huì)生成 l_LuaScript.cpp 來實(shí)行l(wèi)ua和c++ 之間的相互調(diào)用,這里由于是生成出來的 就不粘代碼了

值得注意的幾個(gè)方面:
使用 boost 的時(shí)候?yàn)榱朔奖?我們使用了 BOOST_ALL_NO_LIB ,這樣 就不用編譯 boost了
//  "boost/config/user.hpp" 取消 BOOST_ALL_NO_LIB 注釋
#define  BOOST_ALL_NO_LIB

注意 tolua中 注釋的使用,如果沒使用
   //tolua_export、//tolua_begin、//tolua_end 是無法在實(shí)行 glue.bat 時(shí)生成的 l_LuaScript.cpp 中生成關(guān)聯(lián)映射的。

工程配置:
附加包含目錄:..;..\include;..\..\lua\src;..\..\tolua\include;
附加依賴項(xiàng):lua.lib;tolua.lib;
預(yù)處理器定義:WIN32;_CRT_SECURE_NO_WARNINGS;


main.cpp
#include "ScriptVM.h"
#include "ScriptVmArgs.h"
#include <stdio.h>
#include <string>
#include <assert.h>
#include <iostream>

extern "C" {
    #include "lua.h"
    #include "lualib.h"
    #include "lauxlib.h"
}


#include "tolua++.h"

#include "IOServer.h"
#include "Stream.h"
#include "Hag.h"

#include "FSWrapper.h"

#include "boost/ref.hpp"


extern void report_last_error(lua_State *L, bool bUseAssert);
extern int  tolua_LuaScript_open(lua_State* tolua_S);

static int OverrideDofile(lua_State * L) {

    int n = lua_gettop(L);  /* number of arguments */
    lua_getglobal(L, "tostring");

    if (n != 1)
        return luaL_error(L, "'dofile' param error!");

    std::string sFileName = "";
    lua_pushvalue(L, -1);  /* function to be called */
    lua_pushvalue(L, 1);   /* value to print */
    lua_call(L, 1, 1);
    sFileName = lua_tostring(L, -1);  /* get result */
    if (sFileName == "")
        return luaL_error(L, "'dofile' param error!");

    sFileName = Internal::FSWrapper::GetBinDirectory().c_str();
    sFileName.append("/Scripts/test.lua");
    lua_pop(L, 1);  /* pop result */

                    //get chunk name as modified script name
    std::string sChunkName(sFileName.c_str());
    for (unsigned int i = 0; i < sChunkName.length(); i++)
    {
        if (sChunkName[i] == '/' || sChunkName[i] == '.')
            sChunkName[i] = '_';
    }

    //load it first
    unsigned char * pBuff;
    int nSize;
    if (ScriptVM::LoadFileToBuffer(sFileName.c_str(), pBuff, nSize, true))
    {
        luaL_loadbuffer(L, (char *)pBuff, nSize, sFileName.c_str());

        delete[] pBuff;

        //luaL_loadfile(L, sScriptName);
        lua_setglobal(L, sChunkName.c_str());
        lua_getglobal(L, sChunkName.c_str());

        if (lua_pcall(L, 0, 0, 0) != 0)
        {
            //printf("文件 " << sFileName.c_str() << " 執(zhí)行錯(cuò)誤!");
            std::string sErrorMsg = "error executing script file %s: ";
            sErrorMsg += sFileName;
            assert(sErrorMsg.c_str());
            //error_msg(true, "error executing script file %s: ", sFileName.AsCharPtr());
            report_last_error(L, true);
        }
    }
    else
    {

        lua_settop(L, n);
        return luaL_error(L, "error in the file!");
    }

    return 0;
}

int main(int argc, char** argv) 
{
    ScriptVM* pScriptVM = new ScriptVM;
    if (!pScriptVM->Init())
    {
        printf("ScriptVM Init failed! \n");
        return -1;
    }

    pScriptVM->RegistGlobalFunction("dofile", OverrideDofile);
     //  注意調(diào)用 tolua_LuaScript_open ,使lua和c++可以相互調(diào)用
    tolua_LuaScript_open(pScriptVM->GetLuaState());

    //  加載一個(gè)lua腳本
    pScriptVM->ExecuteScriptFile("scripts/hello.lua");

    
    // 調(diào)用 lua 中的 student_run 方法 , ("i", 20) 表示傳參, i 表示傳一個(gè)參數(shù) 為int型
    
// 假設(shè)要傳 兩個(gè)參數(shù) 一個(gè)是 double 一個(gè)是 std::string 可以寫成 ("ds", 3.14, "vic.MINg")
    std::vector<const char *>modules;
    pScriptVM->ExecuteScriptFunc(modules, "student_run", false, "i", 20);

    
    // 調(diào)用 lua 中的 add 方法
    
// inTuple 為進(jìn)參、 outTuple 為出參
    
//  調(diào)用方法如下 
    int a = 20, b = 10;
    int  sum = 0;
    boost::tuple<intint> inTuple = boost::tuples::make_tuple(a, b);
    boost::tuple<int&> outTuple = boost::tuples::make_tuple(boost::ref(sum));
    pScriptVM->ExecuteFunc("add", false, inTuple, outTuple);
    printf("Lua Func Add %d + %d = %d \n", a, b, sum);


    // 這里我們 傳一個(gè)字符串 來在lua中 new一個(gè) 新類
    
// 看似比較平庸,我們可以通過某些文件來動(dòng)態(tài)生成一個(gè)類 
    
// 比如  我們?cè)?nbsp;xml 中定義一個(gè) <HagType>PlayerHag</HagType>
    
//  然后 讀取該項(xiàng) 然后 類型下面代碼 生成 PlayerHag, 然后通過 RTTI 來判斷 應(yīng)用該類 
    std::string strHag = "english_hag = nil english_hag = Hag:new()";
    pScriptVM->ExecuteScript(strHag.c_str());
    Hag* pEnglish_hag = static_cast<Hag*>(pScriptVM->GetGlobalUserdata("english_hag"));
    if (pEnglish_hag)
    {
        pEnglish_hag->hag_id = 1;
        pEnglish_hag->hag_name = "English";
        pEnglish_hag->is_valid = true;
        pEnglish_hag->hag_score = 94;    
    }


    // 通過 lua 快速公式計(jì)算
    std::string strFormula = "1.8586*level + 8.7842  +50+(level-1)*5/3";
    std::map<std::stringdouble> mapParams;
    mapParams.insert(std::make_pair( "level", 3));
    double dValue = pScriptVM->ComputingFormula(strFormula.c_str(), mapParams);
    printf("Lua ComputingFormula level = %d, 1.8586*level + 8.7842  +50+(level-1)*5/3 =  %lf \n", 3, dValue);

    system("pause");

    return 0;
}

/*        下面的代碼 是處理 原生的 lua腳本的
using namespace std;

void main()
{
    //1.創(chuàng)建Lua狀態(tài)  
    lua_State *L = luaL_newstate();
    if (L == NULL)
    {
        return;
    }

    //2.加載Lua文件  
    int bRet = luaL_loadfile(L, "E:\\hello.lua");
    if (bRet)
    {
        cout << "load file error" << endl;
        return;
    }

    //3.運(yùn)行Lua文件  
    bRet = lua_pcall(L, 0, 0, 0);
    if (bRet)
    {
        cout << "pcall error" << endl;
        return;
    }

    //4.讀取變量  
    lua_getglobal(L, "str");
    string str = lua_tostring(L, -1);
    cout << "str = " << str.c_str() << endl;        //str = I am so cool~  

                                                    //5.讀取table  
    lua_getglobal(L, "tbl");
    lua_getfield(L, -1, "name");
    str = lua_tostring(L, -1);
    cout << "tbl:name = " << str.c_str() << endl; //tbl:name = shun  

                                                  //6.讀取函數(shù)  
    lua_getglobal(L, "add");        // 獲取函數(shù),壓入棧中  
    lua_pushnumber(L, 10);          // 壓入第一個(gè)參數(shù)  
    lua_pushnumber(L, 20);          // 壓入第二個(gè)參數(shù)  
    int iRet = lua_pcall(L, 2, 1, 0);// 調(diào)用函數(shù),調(diào)用完成以后,會(huì)將返回值壓入棧中,2表示參數(shù)個(gè)數(shù),1表示返回結(jié)果個(gè)數(shù)。  
    if (iRet)                       // 調(diào)用出錯(cuò)  
    {
        const char *pErrorMsg = lua_tostring(L, -1);
        cout << pErrorMsg << endl;
        lua_close(L);
        return;
    }
    if (lua_isnumber(L, -1))        //取值輸出  
    {
        double fValue = lua_tonumber(L, -1);
        cout << "Result is " << fValue << endl;
    }

    system("pause");
    //至此,棧中的情況是:  
    //=================== 棧頂 ===================   
    //  索引  類型      值  
    //   4   int:      30   
    //   3   string:   shun   
    //   2   table:     tbl  
    //   1   string:    I am so cool~  
    //=================== 棧底 ===================   

    //7.關(guān)閉state  
    lua_close(L);
    return;
}
*/

LuaScript項(xiàng)目

這個(gè)項(xiàng)目 使用BabeLua插件創(chuàng)建,方便lua腳本的編寫和調(diào)試。

hello.lua
str = "I am so cool"  
tbl = {name = "shun", id = 20114442}  

function add(a,b)  
    return a + b 
end

function student_run(n)
    local st = Student:new() 
    st:Run(n)
    st:delete()
    show_luaproject_info()
end 
OK 這樣一套完善的lua與c++相互交互體系就這樣實(shí)現(xiàn)了,運(yùn)行結(jié)果如下~~~~~~~~~~~




posted on 2018-09-26 15:53 vic.MINg 閱讀(4658) 評(píng)論(0)  編輯 收藏 引用 所屬分類: C/C++

只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理



<2025年9月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用鏈接

留言簿(1)

隨筆分類(13)

隨筆檔案(12)

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国产香蕉97碰碰久久人人| 久久久久国色av免费观看性色| 欧美高清视频在线| 裸体一区二区| 免费国产一区二区| 欧美成人在线影院| 欧美日韩一区不卡| 国产精品亚洲综合| 激情亚洲一区二区三区四区| 激情亚洲网站| 中文在线不卡视频| 久久精品国产999大香线蕉| 久久三级视频| 91久久精品国产91久久性色| 欧美二区视频| 一区二区三区av| 欧美一级片在线播放| 免费国产一区二区| 国产精品视频久久| 老色鬼精品视频在线观看播放| 亚洲精品日韩综合观看成人91| 一本到高清视频免费精品| 亚洲一区二区在线看| 久久久99精品免费观看不卡| 亚洲高清色综合| 午夜视黄欧洲亚洲| 欧美精品在欧美一区二区少妇| 国产精品一区一区三区| 亚洲国产精品ⅴa在线观看 | 欧美在线黄色| 欧美另类亚洲| 激情文学一区| 亚洲欧美日韩久久精品| 欧美激情一区二区| 亚洲欧美日韩国产一区| 欧美精品三区| 亚洲电影免费在线| 久久国产视频网站| 亚洲免费精彩视频| 美日韩精品免费| 国产农村妇女精品| 在线视频你懂得一区二区三区| 久久女同互慰一区二区三区| 在线性视频日韩欧美| 欧美成人中文| 亚洲国产一区二区a毛片| 久久激情综合网| 一本色道久久88亚洲综合88| 免费影视亚洲| 亚洲二区视频在线| 久久精视频免费在线久久完整在线看| 日韩亚洲欧美一区| 欧美国产一区二区| 亚洲国产精品一区二区三区| 久久人人爽人人| 欧美一区二区视频在线观看2020| 国产精品国产福利国产秒拍| 99国产精品视频免费观看一公开 | 亚洲一区二区三区欧美| 欧美激情第8页| 久久午夜精品一区二区| 国产一区二区三区日韩| 久久xxxx| 久久成人18免费网站| 国产午夜精品在线观看| 久久动漫亚洲| 久久精品国产久精国产一老狼 | 亚洲一二三级电影| 亚洲精品资源| 欧美性一区二区| 午夜精品福利视频| 亚洲欧美视频在线观看视频| 国产免费成人av| 久久久久久九九九九| 欧美成人综合网站| 91久久国产精品91久久性色| 女女同性女同一区二区三区91| 久久久久九九视频| 在线免费观看欧美| 亚洲国产一区二区三区在线播| 欧美成人国产一区二区| 一本到12不卡视频在线dvd| 亚洲一区二区黄| 国产综合色产| 亚洲黄色尤物视频| 国产精品每日更新在线播放网址| 欧美一区二区三区在线看| 久久女同互慰一区二区三区| 亚洲精品久久久久久久久久久久 | 国产精品爽爽爽| 久久久免费av| 欧美日韩国产亚洲一区| 欧美一区二区三区视频在线观看 | 久久久美女艺术照精彩视频福利播放 | 欧美激情成人在线视频| 欧美日韩专区| 久久久免费av| 欧美激情五月| 久久综合色天天久久综合图片| 欧美国产高潮xxxx1819| 性做久久久久久| 欧美 日韩 国产 一区| 亚洲欧美视频在线观看视频| 久久香蕉国产线看观看av| 一区二区三区国产| 欧美在线视频日韩| 在线综合亚洲欧美在线视频| 久久精品一本| 亚洲欧美日韩直播| 欧美成人精精品一区二区频| 欧美一区二区三区日韩视频| 欧美激情免费在线| 久久久久久久91| 国产精品视频yy9299一区| 亚洲电影免费| 黄色精品免费| 亚洲欧美第一页| 亚洲色无码播放| 欧美成人按摩| 欧美激情亚洲| 一区二区亚洲欧洲国产日韩| 亚洲嫩草精品久久| 亚洲综合国产| 国产精品白丝黑袜喷水久久久| 亚洲人成毛片在线播放女女| 亚洲东热激情| 久久亚裔精品欧美| 另类尿喷潮videofree | 欧美激情按摩在线| 中文精品在线| 中文在线不卡视频| 欧美成人四级电影| 欧美国产亚洲精品久久久8v| 国色天香一区二区| 欧美一级电影久久| 久久精品亚洲| 精品不卡一区二区三区| 久久九九精品| 女生裸体视频一区二区三区| 好看的日韩视频| 久久久欧美精品sm网站| 免费人成网站在线观看欧美高清| 国产亚洲成av人片在线观看桃| 亚洲自拍偷拍网址| 久久久久国产一区二区| 国产三区精品| 久久婷婷成人综合色| 亚洲成色精品| 亚洲午夜电影在线观看| 国产精品久久国产精品99gif| 在线亚洲一区二区| 欧美一区二区三区日韩| 国产亚洲aⅴaaaaaa毛片| 久久成人国产| 亚洲高清在线精品| 亚洲一区3d动漫同人无遮挡| 国产精品乱码妇女bbbb| 欧美一区二区三区四区在线 | 欧美日韩综合精品| 亚洲免费影视| 麻豆91精品91久久久的内涵| 亚洲高清一区二| 欧美日韩成人免费| 亚洲欧美日本国产专区一区| 久久亚洲高清| 亚洲人成网站777色婷婷| 欧美国产精品人人做人人爱| 亚洲美女黄色| 久久久精品日韩欧美| 亚洲国产精品久久久久久女王| 欧美人牲a欧美精品| 亚洲欧美日韩国产一区| 欧美激情一区二区三区蜜桃视频 | 在线观看亚洲一区| 欧美日韩国产综合视频在线| 午夜精品久久久久久99热软件| 牛人盗摄一区二区三区视频| 一区二区三区精品视频在线观看| 国产精品主播| 欧美激情在线狂野欧美精品| 午夜国产精品影院在线观看| 欧美激情a∨在线视频播放| 亚洲影院色在线观看免费| 悠悠资源网亚洲青| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ入口 | 欧美大片免费观看| 欧美成人亚洲成人| 国产精品国产三级国产a| 久久精品国产一区二区电影| 亚洲精选在线| 美女性感视频久久久| 亚洲欧美日韩在线综合| 亚洲区中文字幕| 好吊妞**欧美| 国产麻豆精品theporn| 欧美激情一区二区三区| 久久亚洲综合网| 欧美专区福利在线| 亚洲欧美综合国产精品一区| 一本到12不卡视频在线dvd |