<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[QUIK -> DDE &mdash; SetUpdateCallback и обнуление стека Lua]]></title>
	<link rel="self" href="https://quik2dde.ru/extern.php?action=feed&amp;tid=446&amp;type=atom" />
	<updated>2023-12-11T07:02:22Z</updated>
	<generator>PunBB</generator>
	<id>https://quik2dde.ru/viewtopic.php?id=446</id>
		<entry>
			<title type="html"><![CDATA[Re: SetUpdateCallback и обнуление стека Lua]]></title>
			<link rel="alternate" href="https://quik2dde.ru/viewtopic.php?pid=4315#p4315" />
			<content type="html"><![CDATA[<p>Нашлось время почитать/вникнуть в ваше сообщение.</p><p>Похоже, вы исходите из ложного убеждения, что передаваемый вам стек Lua - это нечно глобальное и незыблемое. <br />Но это не так.<br />Не готов сейчас указать ссылку на документацию, но помнится такое читал где-то когда-то: стек формируется локально заново для каждого Си+вызова. Ну т.е. не обязательно каждый раз заново, но исходить надо из этого. В любом случае этот стек не является неким глобальным хранилищем, это лишь локальная структура для осуществления каждого отдельного Си-вызова.</p><p>Так что если что-то вам надо передавать из одной части кода в другую - то надо пользоваться либо глобальными переменными С++ для хранения, либо честно через Lua таблицу _G&nbsp; (хранилище глобальных переменных Lua).</p><p>PS<br />Именно поэтому я категорически против написания логики роботов в виде Си-кода. Дело в том, что то, что просто и естественно выглядит в Lua-коде, при переложении на Си-код начинает выглядеть совершенно монтроидозно.</p>]]></content>
			<author>
				<name><![CDATA[swerg]]></name>
				<uri>https://quik2dde.ru/profile.php?id=78</uri>
			</author>
			<updated>2023-12-11T07:02:22Z</updated>
			<id>https://quik2dde.ru/viewtopic.php?pid=4315#p4315</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[SetUpdateCallback и обнуление стека Lua]]></title>
			<link rel="alternate" href="https://quik2dde.ru/viewtopic.php?pid=4312#p4312" />
			<content type="html"><![CDATA[<p>Здравствуйте,</p><p>Раньше все работало, сейчас, как будто бы перестало.</p><p>Естественно использую LUA C API - для вызова SetUpdateCallback, вот такой просто С++ код:&nbsp; да понимаю, что вероятность, что кто-то будет смтреть код стремится к нулю, поэтому срезюмирую поведение кода:</p><p>С помощью QLua C API:</p><p>-1:Я вызываю CreteDataSorce: вызов происходит успешно, мне возвращается таблица и нулевая ошибка.<br />-2:Я подтверждаю это проверкой стека Lua: на вершине стека находится таблица и нулевая ошибка.</p><br /><p>-3:Затем я вызываю SetUpdateCallback и передаю вв него саму колбек функцию, которая будет вызыватся при каждой совершенной сделке.&nbsp; Так же дополнительно я связываю по типу лямбды любое значение, чтбы предать для последующего ивзлечения его в самом колбеке.</p><p>-4:Вызыва SetUpdateCallback, убеждаюсь, что вызов SetUpdateCallback прошел успешно и опять проверяю стек на наличие ранее заказанной таблицы CreateDataSource - ОНИ НА МЕСТЕ!<br />.<br />-5: И наконец на рынке совершается сделка по заказанному инстурменту и вызывается колбек &quot;my_callback__for__SetUpdateCallback&quot;. Все что я делаю в данном примере в этом колбеке это проверяю наличие моей таблицы CrateDataSourc в стеке Lua. ИИИИИИ ее там нет!!!! Весь стека кромер первого элемента был &quot;кем-то&quot; очищен!</p><p>ВОПРОС: КТО И ЗАЧЕМ очитстил стек ?? КАК видно из кода, между вызовов SetUpdateCallback и вызовом самой колбек-функции нет ни одной строчки кода, которая бы редактировала стек. Так что происходит тогда ?</p><br /><br /><br /><div class="codebox"><pre><code>lua_State* L_global;
int static nummer_table_from_stack;</code></pre></div><br /><br /><br /><div class="codebox"><pre><code>void SetUpdateCallcak_wrapper(lua_State* L)
{

    L_global = L;
    std::cout &lt;&lt; &quot;L_global_adress:&quot; &lt;&lt; &amp;L_global &lt;&lt; std::endl;


    //-----------------------------------------------------------------1-Вызовем функцию CreateDataSource:Начало--------------------------------------------
    lua_getglobal(L, &quot;CreateDataSource&quot;);                 

    lua_pushstring(L, &quot;TQBR&quot;);       //Добавим первый параметр функции CreateDataSource на вершину стека
    lua_pushstring(L, &quot;SBER&quot;);          //Добавим второй параметр функции 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 &lt;&lt; &quot;ERROR CreateDataSource&quot; &lt;&lt; std::endl;
        return;
    }
    //-------------------------------------------------------------------5-Проверка на ошибку lua_pcall:Конец---------------------------------------------------------------------
    else
    {

         nummer_table_from_stack = lua_gettop(L) - 1;   //Это номер элемента в стеке L - в котором теперь размещается полученная от CreateDataSource таблица. &quot;-1&quot; - потому что CreateDataSource поместила на вершину стека две перменные: таблицу и переменную об ошибке. То есть таблица находить на предпоследнем месте с вершины стека.

         my_call_SetUpdateCallback(L);     //Вызываем SetUpdateCallback wrapper
    }

}</code></pre></div><br /><br /><div class="codebox"><pre><code>l
static void ckeck_Lua_Stack(lua_State* L)
{

    std::cout &lt;&lt; &quot;----------------------------------------&quot; &lt;&lt; std::endl;

    int top = lua_gettop(L);
    std::cout &lt;&lt; &quot;Total element is stack:&quot;&lt;&lt; top &lt;&lt; std::endl;

    for (int i = 1; i &lt;= top; i++) 
    {
        int type = lua_type(L, i);

        const char* type_name = lua_typename(L, type);

        std::cout &lt;&lt; &quot;type:&quot; &lt;&lt; type_name &lt;&lt; &quot;:&quot;;


        if (type == LUA_TSTRING || type == LUA_TNUMBER) 
        {
            std::cout &lt;&lt; lua_tostring(L, i) &lt;&lt; std::endl;
        }
        else
        {
            std::cout &lt;&lt; std::endl;
        }
    }
    std::cout &lt;&lt; &quot;----------------------------------------&quot; &lt;&lt; std::endl &lt;&lt; std::endl;


    //std::this_thread::sleep_for(std::chrono::milliseconds(100000));

}</code></pre></div><br /><br /><div class="codebox"><pre><code>static int my_callback__for__SetUpdateCallback(lua_State* L)
{

//Значит произошла сделка!

    std::cout &lt;&lt; &quot;Number_candle:&quot;&lt;&lt; lua_tonumber(L, -1) &lt;&lt; std::endl;

    ckeck_Lua_Stack(L_global);         //Проверяем стек Lua!!! И теперь в нем находится сдедующее:

----------------------------------------
Total element is stack:1                          //Куда черт возьми делать моя ранее заказанная таблица CreateDataSource ?????
type:number:1
----------------------------------------


    return 0;

}</code></pre></div><br /><br /><br /><div class="codebox"><pre><code>static void my_call_SetUpdateCallback(lua_State* L)
{

    
    //--------------------------------------------------------
    lua_getfield(L_global, nummer_table_from_stack, &quot;SetUpdateCallback&quot;);                       //&quot;Извлекаем&quot; из &quot;таблицы&quot; функцию 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 &lt;&lt; &quot;lua_pcall__ERROR&quot; &lt;&lt; std::endl;
        return; 
    }
    else
    {
        std::cout &lt;&lt; &quot;SetUpdateCallback Success Call&quot; &lt;&lt; std::endl;
        
        ckeck_Lua_Stack(L_global);       //Проверяю что находится на данный момент в стеке Lua.

       //Находится следующее:

 ----------------------------------------
Total element is stack:3
type:string:1     //Таблица глобьальный функций
type:table:        //Это как раз запрошенная таблица CreateDataSource
type:nil:            //Ошибка при запросе таблицы CreateDataSource - то есть nil - ошибки нет.
----------------------------------------

        return;
    }


}</code></pre></div>]]></content>
			<author>
				<name><![CDATA[Serg_]]></name>
				<uri>https://quik2dde.ru/profile.php?id=3371</uri>
			</author>
			<updated>2023-12-07T08:04:48Z</updated>
			<id>https://quik2dde.ru/viewtopic.php?pid=4312#p4312</id>
		</entry>
</feed>
