Тема: SetUpdateCallback и обнуление стека Lua
Здравствуйте,
Раньше все работало, сейчас, как будто бы перестало.
Естественно использую LUA C API - для вызова SetUpdateCallback, вот такой просто С++ код: да понимаю, что вероятность, что кто-то будет смтреть код стремится к нулю, поэтому срезюмирую поведение кода:
С помощью QLua C API:
-1:Я вызываю CreteDataSorce: вызов происходит успешно, мне возвращается таблица и нулевая ошибка.
-2:Я подтверждаю это проверкой стека Lua: на вершине стека находится таблица и нулевая ошибка.
-3:Затем я вызываю SetUpdateCallback и передаю вв него саму колбек функцию, которая будет вызыватся при каждой совершенной сделке. Так же дополнительно я связываю по типу лямбды любое значение, чтбы предать для последующего ивзлечения его в самом колбеке.
-4:Вызыва SetUpdateCallback, убеждаюсь, что вызов SetUpdateCallback прошел успешно и опять проверяю стек на наличие ранее заказанной таблицы CreateDataSource - ОНИ НА МЕСТЕ!
.
-5: И наконец на рынке совершается сделка по заказанному инстурменту и вызывается колбек "my_callback__for__SetUpdateCallback". Все что я делаю в данном примере в этом колбеке это проверяю наличие моей таблицы CrateDataSourc в стеке Lua. ИИИИИИ ее там нет!!!! Весь стека кромер первого элемента был "кем-то" очищен!
ВОПРОС: КТО И ЗАЧЕМ очитстил стек ?? КАК видно из кода, между вызовов SetUpdateCallback и вызовом самой колбек-функции нет ни одной строчки кода, которая бы редактировала стек. Так что происходит тогда ?
lua_State* L_global;
int static nummer_table_from_stack;
void SetUpdateCallcak_wrapper(lua_State* L)
{
L_global = L;
std::cout << "L_global_adress:" << &L_global << std::endl;
//-----------------------------------------------------------------1-Вызовем функцию CreateDataSource:Начало--------------------------------------------
lua_getglobal(L, "CreateDataSource");
lua_pushstring(L, "TQBR"); //Добавим первый параметр функции CreateDataSource на вершину стека
lua_pushstring(L, "SBER"); //Добавим второй параметр функции CreateDataSource на вершину стека
lua_pushnumber(L, 1); //Добавим третий параметр функции CreateDataSource на вершину стека
int status_lua_pcall = lua_pcall(L, 3, 2, 0); //Так как все необходимые параметры добавлены в стек, то вызываем функцию lua_pcall - которая использя доабвенные параметры в правильном порядке - реализует вызов функции CreateDataSource: 2-ой параметр - это число аргументов, которые мы добаили в стек и которая принимает функция CreateDataSource; 2-ой: параметр - это число параметров, которое возвращает функция CreateDataSource. После успешного выполнения lua_pcall удаляет и значение функции и переданные аргменты со стека в кол-во указанном во втором параметре(не велючая функцию) и доабвляеи результат на стек в кол-во указанном во втором параметре.
//-----------------------------------------------------------------1-Вызовем функцию CreateDataSource:Конец--------------------------------------------
//-------------------------------------------------------------------5-Проверка на ошибку lua_pcall:Начало---------------------------------------------------------------------
if (status_lua_pcall != 0)
{
//Ошибка произошла при вызове функции lua_pcall при вызове CreateDataSource:
std::cout << "ERROR CreateDataSource" << std::endl;
return;
}
//-------------------------------------------------------------------5-Проверка на ошибку lua_pcall:Конец---------------------------------------------------------------------
else
{
nummer_table_from_stack = lua_gettop(L) - 1; //Это номер элемента в стеке L - в котором теперь размещается полученная от CreateDataSource таблица. "-1" - потому что CreateDataSource поместила на вершину стека две перменные: таблицу и переменную об ошибке. То есть таблица находить на предпоследнем месте с вершины стека.
my_call_SetUpdateCallback(L); //Вызываем SetUpdateCallback wrapper
}
}
l
static void ckeck_Lua_Stack(lua_State* L)
{
std::cout << "----------------------------------------" << std::endl;
int top = lua_gettop(L);
std::cout << "Total element is stack:"<< top << std::endl;
for (int i = 1; i <= top; i++)
{
int type = lua_type(L, i);
const char* type_name = lua_typename(L, type);
std::cout << "type:" << type_name << ":";
if (type == LUA_TSTRING || type == LUA_TNUMBER)
{
std::cout << lua_tostring(L, i) << std::endl;
}
else
{
std::cout << std::endl;
}
}
std::cout << "----------------------------------------" << std::endl << std::endl;
//std::this_thread::sleep_for(std::chrono::milliseconds(100000));
}
static int my_callback__for__SetUpdateCallback(lua_State* L)
{
//Значит произошла сделка!
std::cout << "Number_candle:"<< lua_tonumber(L, -1) << std::endl;
ckeck_Lua_Stack(L_global); //Проверяем стек Lua!!! И теперь в нем находится сдедующее:
----------------------------------------
Total element is stack:1 //Куда черт возьми делать моя ранее заказанная таблица CreateDataSource ?????
type:number:1
----------------------------------------
return 0;
}
static void my_call_SetUpdateCallback(lua_State* L)
{
//--------------------------------------------------------
lua_getfield(L_global, nummer_table_from_stack, "SetUpdateCallback"); //"Извлекаем" из "таблицы" функцию SetUpdateCallback.
lua_pushvalue(L_global, nummer_table_from_stack); //Помещаем копию обьекта таблицы CreateDataSource на вершину стека.
//--------------------------------------------------------
lua_pushnumber(L_global, 555); //Просто для примера связываю какое то любое значение для передачи в колбек.
lua_pushcclosure(L_global, my_callback__for__SetUpdateCallback, 1); //Захватываем.
//--------------------------------------------------------
int status_lua_pcall = lua_pcall(L_global, 2, 0, 0); //Реализауем вызов функции SetUpdateCallback с аргументом таблицы, которую поместили на вершину стека
//--------------------------------------------------------
if (status_lua_pcall != 0)
{
std::cout << "lua_pcall__ERROR" << std::endl;
return;
}
else
{
std::cout << "SetUpdateCallback Success Call" << std::endl;
ckeck_Lua_Stack(L_global); //Проверяю что находится на данный момент в стеке Lua.
//Находится следующее:
----------------------------------------
Total element is stack:3
type:string:1 //Таблица глобьальный функций
type:table: //Это как раз запрошенная таблица CreateDataSource
type:nil: //Ошибка при запросе таблицы CreateDataSource - то есть nil - ошибки нет.
----------------------------------------
return;
}
}