• lua调用C++函数


    第一步搭建lua的环境.

    win10 lua环境搭建-CSDN博客

    我使用的环境是win10+vs2015+lua54

    先来个最简单的lua调用C++函数,

    无参数无返回值的

    第一步:定义C++函数.

    1. int CTest(lua_State* L) // 返回值是固定的int类型,返回0表示没有返回参数,返回1表示有一个返回参数
    2. {
    3. std::cout << "int CTest" << std::endl;
    4. return 0;
    5. }

    这个函数,除了函数名可以自己定义其他的都要按这个来定义.

    返回值是固定的int类型,返回0表示没有返回参数,返回1表示有一个返回参数.

    第二步:注册函数.

    lua_register(lua,"CTest",CTest); 

    第一个参数是lua的lua_State的指针,第二个是lua的注册函数名字,这个名字是在lua代码里使用的,第三个参数是函数指针就是刚才定义的C++函数.

    1. #include
    2. extern "C"
    3. {
    4. #include
    5. #include
    6. #include
    7. }
    8. int CTest(lua_State* L) // 返回值是固定的int类型,返回0表示没有返回参数,返回1表示有一个返回参数
    9. {
    10. std::cout << "int CTest" << std::endl;
    11. return 0;
    12. }
    13. int main()
    14. {
    15. lua_State *lua = luaL_newstate();
    16. luaopen_base(lua);
    17. luaopen_string(lua);
    18. lua_register(lua,"CTest",CTest); //第一个参数是lua状态指针,第二个参数是函数名称,第三个参数是lua函数指针,第二个参数和第三个参数可以用不同的名字,但第三个必须使用正确的函数指针
    19. luaL_loadfile(lua, "D:\\code\\MyCode\\C++\\Lua\\CPPAddLua\\testLua\\x64\\Debug\\main.lua");
    20. lua_pcall(lua, 0,0,0);
    21. getchar();
    22. return 0;
    23. }

    直接运行

    这样就是lua调用到了C++函数.当然这里lua调用C++ 函数是指在C++代码中的调用.

    lua传递参数,没有返回值

    只需要从lua的堆栈拿出一个参数即可.在此之前还需要再注册一下.

    lua_register(lua, "CTestToString", CTestToString);
    const char* luaStr = lua_tostring(L,1);

     这样得到的就是lua传递的参数.

    1. int CTestToString(lua_State* L)
    2. {
    3. const char* luaStr = lua_tostring(L,1);
    4. std::cout << luaStr << std::endl;
    5. return 0;
    6. }

     

     传第二个参数就再获取一下第二个参数.

     

    int num = lua_tointeger(L,2);
    1. int CTestToString(lua_State* L)
    2. {
    3. const char* luaStr = lua_tostring(L,1);
    4. std::cout << luaStr << std::endl;
    5. int num = lua_tointeger(L,2);
    6. std::cout << num << std::endl;
    7. return 0;
    8. }

     

    传递普通参数就这样传递.

    lua传递数组给C++函数

    第一步注册函数:

    lua_register(lua, "CTestArr", CTestArr);

    第二步:编写接收函数

    1. int CTestArr(lua_State* L)
    2. {
    3. std::vector vStr;
    4. std::cout << "int CTestArr" << std::endl;
    5. int arraySize = luaL_len(L, 1); //获取表的大小
    6. for (int i = 1; i <= arraySize; ++i)
    7. {
    8. lua_pushnumber(L,i); //往栈中压入一个数字,表示从数组中取那个下标的值,lua都是从1开始的所以i从1开始
    9. lua_gettable(L, 1); //把上一行索引的位置出栈,再把i压入 栈
    10. vStr.push_back(lua_tostring(L,-1));
    11. lua_pop(L,1);
    12. }
    13. for (auto& value : vStr)
    14. {
    15. std::cout << value << std::endl;
    16. }
    17. return 0;
    18. }

    第三步:lua调用

    .

    lua传递表给C++函数

    lua_next3(L,3)

    1. 先从栈顶弹出一个key
    2. 从栈指定位置的table里取下一对key-value,先将key入栈再将value入栈
    3. 如果第2步成功则返回非0值,否则返回0,并且不向栈中压入任何值.

    第一步注册函数:

    lua_register(lua, "CTestTable", CTestTable);

    第二步:

    1. int CTestTable(lua_State* L)
    2. {
    3. std::cout << "int CTestTable" << std::endl;
    4. std::map mStr;
    5. lua_pushnil(L);
    6. while (lua_next(L, 1) != 0)
    7. {
    8. mStr[lua_tostring(L, -2)] = lua_tostring(L,-1);
    9. lua_pop(L,1);
    10. }
    11. for (auto& value : mStr)
    12. {
    13. std::cout << value.first << " = " << value.second << std::endl;
    14. }
    15. return 0;
    16. }

    第三步lua调用:

     结果:

    lua调用C++ 获取表中的内容

    1. lua_getfield(L,1,"name");
    2. std::cout << lua_tostring(L,-1) << std::endl;

    Lua调用C++参数类型检查

    1. luaL_checktype(L,1,LUA_TBOOLEAN);
    2. if (lua_type(L, 1) != LUA_TBOOLEAN)
    3. {
    4. luaL_argerror(L,1,"bad argument");
    5. }

    第一行,一旦不匹配代码就不会往下执行,

    第二行的不匹配还会往下执行.

    Lua调用C++ 返回值普通类型

    第一步:注册函数:

    lua_register(lua, "TestRe", TestRe);

    第二步写函数:

    1. int TestRe(lua_State* L)
    2. {
    3. lua_pushstring(L,"return value");
    4. return 1;
    5. }

    一个返回参数就返回1,两个就返回2

    第三步lua代码

    结果:

    lua返回表

    第一步注册函数:

    lua_register(lua, "TestReTable", TestReTable);

    第二步写注册函数

    1. int TestReTable(lua_State* L)
    2. {
    3. lua_newtable(L); // 创建一个表格,放在栈顶
    4. lua_pushstring(L,"name"); // 压入key
    5. lua_pushstring(L,"ccname");//压入value
    6. lua_settable(L,-3); //弹出key value,并设置到表,表在栈顶了作为返回值
    7. lua_pushstring(L, "age"); // 压入key
    8. lua_pushinteger(L, 21);//压入value
    9. lua_settable(L, -3); //弹出key value,并设置到表,表在栈顶了作为返回值
    10. return 1;
    11. }

    第三步:lua

    结果:

    C++全部代码:

    1. #include
    2. extern "C"
    3. {
    4. #include
    5. #include
    6. #include
    7. }
    8. #include
    9. #include
    10. #include
    11. int CTest(lua_State* L) // 返回值是固定的int类型,返回0表示没有返回参数,返回1表示有一个返回参数
    12. {
    13. std::cout << "int CTest" << std::endl;
    14. return 0;
    15. }
    16. int CTestToString(lua_State* L)
    17. {
    18. const char* luaStr = lua_tostring(L,1);
    19. std::cout << luaStr << std::endl;
    20. int num = lua_tointeger(L,2);
    21. std::cout << num << std::endl;
    22. bool is = lua_toboolean(L, 3);
    23. std::cout << is << std::endl;
    24. return 0;
    25. }
    26. int CTestArr(lua_State* L)
    27. {
    28. std::vector vStr;
    29. std::cout << "int CTestArr" << std::endl;
    30. int arraySize = luaL_len(L, 1); //获取表的大小
    31. for (int i = 1; i <= arraySize; ++i)
    32. {
    33. lua_pushnumber(L,i); //往栈中压入一个数字,表示从数组中取那个下标的值,lua都是从1开始的所以i从1开始
    34. lua_gettable(L, 1); //把上一行索引的位置出栈,再把i压入 栈
    35. vStr.push_back(lua_tostring(L,-1));
    36. lua_pop(L,1);
    37. }
    38. for (auto& value : vStr)
    39. {
    40. std::cout << value << std::endl;
    41. }
    42. return 0;
    43. }
    44. int CTestTable(lua_State* L)
    45. {
    46. std::cout << "int CTestTable" << std::endl;
    47. /* 读取全部的表的内容 */
    48. std::map mStr;
    49. lua_pushnil(L);
    50. while (lua_next(L, 1) != 0)
    51. {
    52. mStr[lua_tostring(L, -2)] = lua_tostring(L,-1);
    53. lua_pop(L,1);
    54. }
    55. for (auto& value : mStr)
    56. {
    57. std::cout << value.first << " = " << value.second << std::endl;
    58. }
    59. /* 只取一个
    60. lua_getfield(L,1,"name");
    61. std::cout << lua_tostring(L,-1) << std::endl;
    62. */
    63. return 0;
    64. }
    65. int TestRe(lua_State* L)
    66. {
    67. lua_pushstring(L,"return value");
    68. return 1;
    69. }
    70. int TestReTable(lua_State* L)
    71. {
    72. lua_newtable(L); // 创建一个表格,放在栈顶
    73. lua_pushstring(L,"name"); // 压入key
    74. lua_pushstring(L,"ccname");//压入value
    75. lua_settable(L,-3); //弹出key value,并设置到表,表在栈顶了作为返回值
    76. lua_pushstring(L, "age"); // 压入key
    77. lua_pushinteger(L, 21);//压入value
    78. lua_settable(L, -3); //弹出key value,并设置到表,表在栈顶了作为返回值
    79. return 1;
    80. }
    81. int main()
    82. {
    83. lua_State *lua = luaL_newstate();
    84. luaopen_base(lua);
    85. luaopen_string(lua);
    86. lua_register(lua,"CTest",CTest); //第一个参数是lua状态指针,第二个参数是函数名称,第三个参数是lua函数指针,第二个参数和第三个参数可以用不同的名字,但第三个必须使用正确的函数指针
    87. lua_register(lua, "CTestToString", CTestToString);
    88. lua_register(lua, "CTestArr", CTestArr);
    89. lua_register(lua, "CTestTable", CTestTable);
    90. lua_register(lua, "TestRe", TestRe);
    91. lua_register(lua, "TestReTable", TestReTable);
    92. luaL_loadfile(lua, "D:\\code\\MyCode\\C++\\Lua\\CPPAddLua\\testLua\\x64\\Debug\\main.lua");
    93. lua_pcall(lua, 0,0,0);
    94. getchar();
    95. return 0;
    96. }

    lua全部代码:

    1. CTest()
    2. CTestToString("lua string",123456,true)
    3. local arr = {"A001","A002","A003"};
    4. CTestArr(arr)
    5. local tab = {name="xiaoming",age="22",id="007"};
    6. CTestTable(tab)
    7. local re = TestRe()
    8. print("re = " .. re)
    9. local retab = TestReTable()
    10. print("name = " .. retab["name"])
    11. print("name = " .. retab["age"])

  • 相关阅读:
    浅析C#中的托管、非托管堆栈与垃圾回收
    Jenkins的job远程触发另一个Jenkins上的job
    无业游民写的最后一个.net有关项目框架
    网络相关linux指令等储备
    一个案例体会Vue的优势
    新一代蒸馏算法
    用Threejs做一只会动的3D玉兔祝大家中秋快乐
    LeetCode_容斥原理_中等_223.矩形面积
    【计算机网络】 TCP流量控制——滑动窗口和累积应答
    驱动开发day2(编程实现LED三盏小灯亮灭)
  • 原文地址:https://blog.csdn.net/m0_38036750/article/details/136429209