Использование Lua для С/C++ приложений

Важной особенностью lua является то, что всё взаимодействие между кодом и виртуальной машиной происходит через стек.

Задача. Требуется сортировать массив и при этом необходимо менять алгоритм сортировки без перекомпиляции приложения. Для этого создадим файл test.lua в котором будет реализован алгоритм быстрой сортировки.
function quikSortXora(a,st,en)
    local i=st;
    local j=en;
    local sr=(i+(j-1))/2;

    sr=math.floor(sr)
    if(sr>en) then
        sr=en;
    end;

    if(sr<=0) then
        sr=st;
    end;

    local p=a[sr];

    repeat
        while(a[i]<p) do i=i+1; end;
        while(a[j]>p) do j=j-1; end;

        if(i<=j) then
            local tmp=a[j];a[j]=a[i];a[i]=tmp;
            i=i+1;
            j=j-1;
        end;
    until (i>j);

    if(i<en) then
        quikSortXora(a,i,en);
    end;

    if(j>0) then
        quikSortXora(a,1,j);
    end;
end;

function quikSort(res)
    quikSortXora(res,1,#res);
    return res;
end;

Все что теперь требуется это вызвать из кода на С++ метод из вышеприведенного файла.
#include "stdafx.h"
// Важно указать стиль импортируемых функций
#ifdef __cplusplus
extern "C" {
#endif
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#ifdef __cplusplus
};
#endif

int _tmain(int argc, _TCHAR* argv[])
{
    //инициализируем виртуальную машину LUA
    lua_State *lua=lua_open();

    if ( lua == NULL )
    {
        printf ( "Ошибка создания VM.\n" );
        return 1;
    }
	
    // Подключаем все стандартные библиотеки
    luaL_openlibs ( lua );                  
                     
    // загружаем lua файл
    if ( luaL_loadfile ( lua, "test.lua" ) )
        printf ( "Ошибка открытия test.lua\n" );

    // инициализируем объекты в сриптовом файле
    lua_pcall(lua,0,LUA_MULTRET,0);

    // помещаем глобальную функцию quikSort из файла в стек
    lua_getfield(lua,LUA_GLOBALSINDEX,"quikSort");
	 
    // создаем таблицу из 5 элементов таблица помещается на вершину стека
    lua_createtable (lua,5,0);
	
    //  Добавление значений в таблицу(для наглядности работы со стеком разбит на команды)

    // помещаем 4 на вершине стека
    lua_pushnumber(lua,4);

    // заносим в таблицу(расположенную в стеке по индексу 2), 
    // значение с вершины стека(4) по индексу table[1]
    lua_rawseti (lua,2, 1 );

    lua_pushnumber(lua,7);
    lua_rawseti (lua,2, 2 );

    lua_pushnumber(lua,2);
    lua_rawseti (lua,2, 3 );

    lua_pushnumber(lua,12);
    lua_rawseti (lua,2, 4 );

    lua_pushnumber(lua,1);
    lua_rawseti (lua,2, 5 );

    // вызываем метод quikSort с одним параметром и одним возвращаемым значением
    lua_call(lua,1,1);

    // получаем число элементов  в таблице результат quikSort, 
    // которая располагается на вершине стека
    int count=lua_objlen(lua,-1);
    int num=0;

    int *buf=new int[count];

    // перебираем все таблици в таблице
    for(int i=1;i<=count;i++)
    {
        // порядковый номер (table[i]) значения в таблице
        lua_pushnumber(lua,i);  
        // получить значение по индексу см выше, из таблицы расположенной по индексу 1 в стеке
        lua_gettable(lua,1);
        // результат предыдущей операции лежит на вершине стека
        num=lua_tonumber(lua,2); 
        // удалим верхний элемент
        lua_pop(lua,1);
        buf[i-1]=num;
    }

    for(int i=0;i<count;i++)
    {
        printf("Result: %d\n", buf[i]); // 1,2,4,7,12
    }

    delete[] buf;
    lua_close( lua );   
    return 0;
}
--
автор:Гетманский Сергей

Last edited Feb 7, 2012 at 4:04 AM by basph, version 5

Comments

No comments yet.