Liny_@NotePad

沉迷ACG中

【20090930】C++培训日记-Lua

YOYO posted @ 2009年10月01日 04:40 in 【C/C++】 with tags Lua LuaPlus , 3220 阅读

今天学习的是Lua的基本语法,以及与C++的相互调用。

在C++中使用Lua,需要导入lua的头文件(lua.h、lualib.h、lauxlib.h),使用lua的lib。这里使用的是5.1版本。
由于lua是用C编写的,因此导入头文件时需要声明extern "C",让h文件用C编译。

  • C++中调用Lua的函数:
    先写一个Lua脚本Cal.lua,完成两个数相加的方法add:
    1. function add(x, y)
    2.         return x + y
    3. end
    在C++中调用该函数(注意函数名大小写)时,需要传入参数,告知lua传入的参数个数和传出参数个数,获得返回值后清栈即可。
    1. //////////////////////////////////////////////////////////////////////////
    2. //      CopyRight(c) 2009, YOYO, All Rights Reserved.
    3. //      Author: LIN YiQian
    4. //      Created: 2009/09/30
    5. //      Describe: C++中调用Lua脚本
    6. //////////////////////////////////////////////////////////////////////////
    7. extern "C"
    8. {
    9. #include "lua.h"
    10. #include "lualib.h"
    11. #include "lauxlib.h"
    12. };
    13.  
    14. #include <iostream>
    15.  
    16. #pragma comment(lib, "lua51.lib")
    17.  
    18. lua_State*      g_pLuaState;
    19.  
    20. /************************************************************************/
    21. /* 使用Lua脚本中的Add函数
    22. /************************************************************************/
    23. int     lua_add(int nNum1, int nNum2)
    24. {
    25.         int sum = 0;
    26.  
    27.         //      获得函数:注意大小写
    28.         lua_getglobal(g_pLuaState, "add");
    29.  
    30.         //      传参
    31.         lua_pushnumber(g_pLuaState, nNum1);
    32.         lua_pushnumber(g_pLuaState, nNum2);
    33.  
    34.         //      执行函数 同时说明参数个数
    35.         lua_call(g_pLuaState, 2, 1);
    36.  
    37.         //      获得返回值
    38.         sum = (int)lua_tonumber(g_pLuaState, -1);
    39.  
    40.         //      清栈
    41.         lua_pop(g_pLuaState, 1);
    42.  
    43.         return sum;
    44. }
    45.  
    46. int main(void)
    47. {
    48.         //      初始化Lua
    49.         g_pLuaState = lua_open();
    50.  
    51.         //      打开文件
    52.         luaL_dofile(g_pLuaState, "Cal.lua");
    53.  
    54.         //      调用函数
    55.         int sum = lua_add(3, 5);
    56.  
    57.         //      打印结果
    58.         std::cout << sum << std::endl;
    59.  
    60.         //      关闭Lua
    61.         lua_close(g_pLuaState);
    62.  
    63.         system("pause");
    64.  
    65.         return 0;
    66. }
  • Lua中调用C++的函数:
    C++中定义函数average,固定格式是static int 函数名(Lua_State* pLuaState),其中int返回值的意思是返回的参数个数。我们可以通过传入的Lua_State*来获得参数。
    在运行lua脚本前向Lua注册该函数,再运行即可使用。详细看代码:
    C++代码:
    1. //////////////////////////////////////////////////////////////////////////
    2. //      CopyRight(c) 2009, YOYO, All Rights Reserved.
    3. //      Author: LIN YiQian
    4. //      Created: 2009/09/30
    5. //      Describe: Lua中读取C++
    6. //////////////////////////////////////////////////////////////////////////
    7. #include <iostream>
    8.  
    9. extern"C" {
    10. #include "lua.h"
    11. #include "lualib.h"
    12. #include "lauxlib.h"
    13. };
    14.  
    15. #pragma comment(lib, "lua51.lib")
    16.  
    17. /************************************************************************/
    18. /* 求平均数函数
    19. /************************************************************************/
    20. static int average(lua_State*   pLuaState)
    21. {
    22.         //      获得参数个数
    23.         int n = lua_gettop(pLuaState);
    24.  
    25.         double sum = 0;
    26.  
    27.         //      从1开始读取第一个参数...
    28.         for (int i = 1; i <= n; ++i)
    29.         {
    30.                 sum += lua_tonumber(pLuaState, i);
    31.         }
    32.  
    33.         double avg = sum / n;
    34.  
    35.         //      放入参数1:平均数
    36.         lua_pushnumber(pLuaState, avg);
    37.  
    38.         //      放入参数2:和
    39.         lua_pushnumber(pLuaState, sum);
    40.  
    41.         //      返回参数个数
    42.         return 2;
    43. }
    44.  
    45. int main(void)
    46. {
    47.         lua_State* pLuaState = lua_open();
    48.  
    49.         //      打开Lua Base库
    50.         luaopen_base(pLuaState);
    51.  
    52.         //      注册C++函数average
    53.         lua_register(pLuaState, "average", average);
    54.  
    55.         //      运行脚本
    56.         luaL_dofile(pLuaState, "test.lua");
    57.  
    58.         lua_close(pLuaState);
    59.  
    60.         system("pause");
    61.  
    62.         return 0;
    63. }
    Lua脚本test.lua:
    1. print(3, 2, 1, 5, 4)
    2. avg, sum = average(3, 2, 1, 5, 4)
    3. print("Average = " , avg, "\nSum = ", sum)
    4. print(5, 6, 7, 8, 9, 10, 11)
    5. avg, sum = average(5, 6, 7, 8, 9, 10, 11)
    6. print("Average = " , avg, "\nSum = ", sum)
  • Lua中调用C++的成员函数:
    由于要调用C++函数已经固定了格式为static int 函数名(LuaState* pLuaState),而成员函数显然不能这样写,于是我们使用LuaPlus,它是Lua For C++的扩展。
    载一个LuaPlus,用release编译工程会在../../lib/win32与../../Bin目录生成LuaPlus_1100.lib和LuaPlus_1100.dll,放到项目目录下,
    设置include目录是luaplus的Src/LuaPlus,即配置完成。

    C++类如往常写法,在运行脚本前要注册该函数,使用你已经创建好的对象:
    1. //////////////////////////////////////////////////////////////////////////
    2. //      CopyRight(c) 2009, YOYO, All Rights Reserved.
    3. //      Author: LIN YiQian
    4. //      Created: 2009/09/30
    5. //      Describe: LuaPlus调用C++成员函数
    6. //////////////////////////////////////////////////////////////////////////
    7. #include <iostream>
    8.  
    9. #include "LuaPlus/LuaPlus.h"
    10. #include "LuaPlus/LuaState.h"
    11.  
    12. #pragma comment(lib, "Lib/LuaPlus_1100.lib")
    13.  
    14. void speak(const char* msg)
    15. {
    16.         std::cout << msg << std::endl;
    17. }
    18.  
    19. class CTest
    20. {
    21. public:
    22.         void speakMember(const char* msg)
    23.         {
    24.                 std::cout << msg << std::endl;
    25.         }
    26.  
    27.         virtual void speakVirtual(const char* nick, const char* msg)
    28.         {
    29.                 std::cout << nick << ": " << msg << std::endl;
    30.         }
    31.  
    32. };
    33.  
    34. int main(void)
    35. {
    36.         LuaState*       pLuaState = LuaState::Create();
    37.         LuaObject       luaObj = pLuaState->GetGlobals();
    38.  
    39.         //      注册全局函数
    40.         luaObj.RegisterDirect("speak", speak);
    41.  
    42.         //      注册成员函数
    43.         CTest objTest;
    44.         luaObj.RegisterDirect("speakMember", objTest, &CTest::speakMember);
    45.         luaObj.RegisterDirect("speakVirtual", objTest, &CTest::speakVirtual);
    46.  
    47.         //      运行脚本
    48.         pLuaState->DoFile("test.lua");
    49.  
    50.         LuaState::Destroy(pLuaState);
    51.  
    52.         system("pause");
    53.  
    54.         return 0;
    55. }
    Lua脚本如下:
    1. speak("hi")
    2. speakMember("hello world")
    3. speakVirtual("YOYO", "Test Success!")
  • 无匹配

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter