• Lua与C的相互调用


    闲的蛋疼,让C和Lua玩包剪锤。结果C以微弱的优势胜出了。

    言归正传,这次主要是想练习Lua和C的相互调用。

    一、C调用Lua函数

    1. luaL_dofile(L, fn);

    该函数可以让Lua虚拟栈读取路径为fn的Lua文件,其实质是:

    lua_loadfile(L, fn) || lua_pcall(L, 0, Lua_MUTIRET, 0)

    实际上,lua_loadfile只是把Lua文件加载到VM,成为一个可执行的对象,但却还没有执行它,所以还不能使用。

    而lua_pcall则把该Lua文件运行了。只有运行了该文件才可以使用其函数。

    2. lua_getglobal(L, s)

    把全局变量s压入栈顶

    3. lua_pushnumber(L, arg)

     把参数压入栈顶。

    4. lua_pcall(L, nargs, nreturns, errorfunc)

    运行栈顶函数,传入参数个数后,虚拟栈会自动pop出相应数量的参数供Lua函数使用。

    二、Lua调用C函数

    1. 首先要在C中注册C函数到Lua虚拟栈 : lua_register(L, n, f)

    可以把名为n的函数f注册到Lua虚拟栈中。其可以分为两步:

    lua_pushcfunction(L, f)

    lua_setglobal(L, n)

    即首先把函数f压入栈顶,再将其pop出来,并设为全局变量。

    2. 在lua中调用C函数,直接调用即可

    3. 该C函数可以用luaL_checknumber(L, idx)获取栈中序号为idx的参数

    4. return 的整型数代表C返回给Lua的返回值个数。 可以先用lua_pushnumber把要返回的值压入栈

    关于石头剪刀布的随机,由于没有去维护一个给lua的全局变量随机种子,故每次用C随机了一颗种子给lua,再让lua产生随机数。

    另外,本人并没有做错误判断和处理,程序的健壮性尚佳,读者们可以自己思考下哪里需要加上错误判断和处理,加强理解。

    代码清单:

    1. lua_psr.lua

    1 function lua_psr (c_r,seed)
    2     math.randomseed(seed);
    3     lua_r = math.random(3)-1;
    4     c_win,c_draw,c_lose = judge(c_r, lua_r);
    5     print_log("the result: c_win = "..c_win.."  c_draw = "..c_draw.."  c_lose = "..c_lose.."
    ");
    6 end
    Lua_psr.lua

    2.  testLua.cpp

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <string>
     4 #include <time.h>
     5 #include <stdlib.h>
     6 extern "C" {
     7 #include <lua.h>
     8 #include <lauxlib.h>
     9 #include <lualib.h>
    10 }
    11 
    12 int c_win;
    13 int c_lose;
    14 int c_draw;
    15 
    16 // called in lua
    17 int print_log(lua_State* L)
    18 {
    19     std::string str = luaL_checkstring(L, 1);
    20     printf("%s", str.c_str());
    21     return 0;
    22 }
    23 
    24 // called in lua
    25 int judge(lua_State *L)
    26 {
    27     int c = luaL_checknumber(L, 1);
    28     int lua = luaL_checknumber(L, 2);
    29     if (0 == c - lua)
    30     {
    31         c_draw++;
    32     }
    33     else if (-1 == c - lua || 2 == c - lua)
    34     {
    35         c_lose++;
    36     }
    37     else
    38     {
    39         c_win++;
    40     }
    41     //printf("now the result is :  c_win=%d c_draw=%d c_lose=%d ",c_win,c_draw,c_lose);
    42     lua_pushnumber(L, c_win);
    43     lua_pushnumber(L, c_draw);
    44     lua_pushnumber(L, c_lose);
    45     return 3;
    46 }
    47 
    48 int psr()
    49 {    
    50     int r = rand()%3;
    51     return r;
    52 }
    53 
    54 void lua_psr(lua_State* L, int r)
    55 {
    56     lua_getglobal(L, "lua_psr");
    57     lua_pushnumber(L, r);
    58     int seed = rand()%100000000;
    59     lua_pushnumber(L, seed);
    60     lua_pcall(L, 2, 0, 0);
    61 }
    62 
    63 int main (void)
    64 {
    65     srand(time(NULL));
    66     freopen("paper_scissor_rock_c_vs_lua_result.txt", "w", stdout);
    67     lua_State *L = luaL_newstate();
    68     luaL_openlibs(L);
    69     if (0 != luaL_dofile(L, "lua_psr.lua"))
    70     {
    71         printf("lua file not found!");
    72         return 0;
    73     }
    74     lua_register(L, "judge", judge);
    75     lua_register(L, "print_log", print_log);
    76     printf("now begin! paper scissor rock c vs lua!
    ");
    77     for (int i = 0; i < 100; i++)
    78     {
    79         int r = psr();
    80         lua_psr(L, r);
    81     }
    82     printf("total turns: %d
    ", c_win + c_draw + c_lose);
    83     printf("c_win: %d
    ", c_win);
    84     printf("c_draw: %d
    ", c_draw);
    85     printf("c_lose: %d
    ", c_lose);
    86     return 0;
    87 }
    testLua.cpp
  • 相关阅读:
    keypress事件
    input输入框(blur,change,focus)
    click点击以后添加新class,删除其余同名class
    强制数组并且匹配Array
    模拟鼠标事件
    简单的form操作
    鼠标滚轮事件(mousewheel、DOMMouseScroll)
    事件委托技术
    从程序员到项目经理:项目经理必须懂一点“章法”
    JavaScript项目优化总结
  • 原文地址:https://www.cnblogs.com/elenno/p/lua_vs_c.html
Copyright © 2020-2023  润新知