1. 程式人生 > >Lua與C的基礎互動

Lua與C的基礎互動

//
//  testLua.cpp
//  testLuaCall
//
//  Created by ljw on 2018/9/26.
//  Copyright © 2018年 x. All rights reserved.
//

#pragma once

#include "lua/lua.h"
#include "lua/lualib.h"
#include "lua/lauxlib.h"
#include "lua_bridge.h"
/*
 #define LUA_TNIL        0
 #define LUA_TBOOLEAN        1
 #define LUA_TLIGHTUSERDATA    2
 #define LUA_TNUMBER        3
 #define LUA_TSTRING        4
 #define LUA_TTABLE        5
 #define LUA_TFUNCTION        6
 #define LUA_TUSERDATA        7
 #define LUA_TTHREAD        8
 */

void dump(lua_State* L)
{
    int top = lua_gettop(L);
    int type = LUA_TNONE;
    char typestr[20];
    for (int i = top; i != 0; i--)
    {
        type = lua_type(L, i); // 獲取type
        switch (type) {
            case LUA_TNIL:
                snprintf(typestr, 20, "nil"); break;
            case LUA_TBOOLEAN:
                snprintf(typestr, 20, "boolean"); break;
            case LUA_TLIGHTUSERDATA:
                snprintf(typestr, 20, "light-userdata"); break;
            case LUA_TNUMBER:
                snprintf(typestr, 20, "number"); break;
            case LUA_TSTRING:
                snprintf(typestr, 20, "string"); break;
            case LUA_TTABLE:
                snprintf(typestr, 20, "table"); break;
            case LUA_TFUNCTION:
                snprintf(typestr, 20, "function"); break;
            case LUA_TUSERDATA:
                snprintf(typestr, 20, "userdta"); break;
            case LUA_TTHREAD:
                snprintf(typestr, 20, "thread"); break;
            default:
                snprintf(typestr, 20, "unknow"); break;
                break;
        }
        printf("[Stack Index:%d]%s\t: %s \n", i, typestr, lua_tostring(L, i));
    }
}

void clearStack(lua_State* L)
{
    lua_pop(L, lua_gettop(L));
}

void doPushStack(lua_State* L)
{
    clearStack(L);
    lua_pushstring(L, "this is test string in stack 1");//棧index = 1
    lua_pushnumber(L, 1); // 棧index = 2
    lua_pushboolean(L, 1); // 棧index = 3
    lua_pop(L, 1); // 從棧頂(最大棧Index)推出一個元素
    dump(L);
    
    clearStack(L);
    dump(L);
}

void doAdd(lua_State* L)
{
    clearStack(L);
    if (luaL_dostring(L, "add = function(x, y) return x + y end"))
    {
        return;
    }
    lua_getglobal(L, "add"); //棧Index = 1
    dump(L);
    lua_pushnumber(L, 1); //棧Index = 2
    lua_pushnumber(L, 2); //棧Index = 3
    //lua_pushnumber(L, 3); //引數個數異常測試
    dump(L);
    lua_pcall(L, 2, 1, 0); //pcall 為執行棧Index 為 1 的方法 第二個引數為z傳入 n 個引數 第三個引數為返回 n 個引數 執行完成之後將pop出 (1(方法棧) + 所有引數個數)個棧內元素 並將返回值入棧 如果引數個數不正確 將返回attempt to call a string value
    dump(L);
    
    clearStack(L);
}

void doDumpTableSimple(lua_State* L)
{
    clearStack(L);
    if (luaL_dostring(L, "testTable = { a = 123, b = 456 , c = 'ccc'}"))
    {
        return;
    }
    lua_getglobal(L, "testTable");
    int idx = lua_gettop(L);
    printf("%d\n", idx);
    lua_pushnil(L);
    while (1)
    {
        if (!lua_next(L, idx))
            break;
        //dump(L);
        printf("[key]:%s, [value]:%s\n", lua_tostring(L, -1), lua_tostring(L, -2));
        lua_pop(L, 1);
        //dump(L);
    }
    //dump(L);
}

void doGetTableValue(lua_State* L)
{
        clearStack(L);
    
    if (luaL_dostring(L, "testTable = { a = 123, b = 456 , c = 'ccc'}"))
    {
        return;
    }
    
    lua_getglobal(L, "testTable"); //棧Index 1
    lua_pushstring(L, "a"); //棧Index 2
    lua_pushstring(L, "b"); //棧Index 3
    lua_pushstring(L, "c"); //棧Index 4
    dump(L);
    lua_gettable(L, 1); //GetTable方法 在棧尾為table的情況下 獲取棧頂所在元素為Key值的元素 並替換該Key元素為Table對應的Value
    dump(L);
}


int cMethod(lua_State* L)
{
    int i = 0;
    int sum = 0;
    //檢索所有的number值
    int NOS = lua_gettop(L);
    while (++i <= NOS) {
        if (lua_isnumber(L, i))
            sum += lua_tointeger(L, i);
        else
            printf("Index %d is not a number!\n", i);
    }
    clearStack(L); //清除棧
    lua_pushnumber(L, sum); //返回值
    return 1;
}

void doCallCMethod(lua_State* L)
{
    clearStack(L);
    lua_register(L, "cMethod", cMethod);
    if (luaL_dostring(L, "print(cMethod(1, 2, 3, 4, 5, saf) or 'failed')"))
    {
        return;
    }
    dump(L);
}


void testLuaStack(lua_State* L)
{
    clearStack(L);
    for (int i = 0; i != 10; ++i) {
        lua_pushnumber(L, i);
    }
    dump(L);
    
    printf("%d\n", lua_tointeger(L, 1)); //1
    printf("%d\n", lua_tointeger(L, 2)); //2
    printf("%d\n", lua_tointeger(L, 3)); //3
    printf("%d\n", lua_tointeger(L, -1)); //10
    printf("%d\n", lua_tointeger(L, -2)); //9
    printf("%d\n", lua_tointeger(L, -3)); //8
    /*
     *  總結 元素入棧時  所有已入棧的元素Index + 1
     *  Indexu最大的為h棧頂
     *  獲取的傳入Index為正數時, 順序為棧頂-棧尾 10-1
     *  獲取的傳入Index為負數時,順序為棧尾-棧頂 1-10
     *
     */
}

void doTest(lua_State* L)
{
    //doPushStack(L);
    //doAdd(L);
    //doGetTableValue(L);
    //doDumpTableSimple(L);
    //doCallCMethod(L);
    testLuaStack(L);
}