Нашёл, в чём проблема. Не сохраняются настройки. После закрытия источника данных и самого скрипта, подписка на поток обезличенных сделок пропадает в меню Система->Заказ данных->Поток обезличенных сделок. Это хорошо. Но, после закрытия терминала, в файле "INFO.INI" в разделе [ALL_TRADES_DATA] подписки остаются. Соответственно, после запуска терминала, эти самые подписки появляются и в вышеуказанном меню. При первом запуске скрипта данных нет. Если предварительно снять галочки в меню подписок, данные появляются при первом же запуске скрипта.
При ручном снятии подписки через меню, настройки сохраняются. А через скрипт - нет.
Николай Камынин написал: Стек в луа - это просто область памяти, указатель на которую находится по адресу L->base При вталкивании в стек данные записываются по адресу, который записан в L->top Сначала там записан L->base, после каждого заталкивания L->top=L->top+1 При выталкивание происходит обратное действие. При этом происходит контроль границ стека и если адрес выходит за границы выдается сообщение луа. ------------------------------- Таким образом, КВИК падать не может из-за операций со стеком. ---------------------------- Если у Вас квик падает без сообщений, то ошибка в Вашем коде CИ, которай приводит к фатальной ошибке, которую никто не обрабатывает. Возможно Вы в своей программе куда-то не туда чего-то пишите. -------------------------------- Все колбеки выполняются в одном потоке. Но вот открытие источников надо делать в main. Не знаю для чего так сделано, но уж сделано.
Спасибо за разъяснения, проверю свой код. Да, ошибки не обрабатываю, нужно это добавить. Источник открываю в main, пока всё работает.
Вячеслав + написал: Если между вызовами Си функций из Lua, то можно сохранить это значение в LUA_REGISTRYINDEX - это специальная таблица, видимая только из Си и хранящая важную информацию (удалять из неё что-то не своё точно не надо). См. API idx = luaL_ref(L, LUA_REGISTRYINDEX) luaL_unref(L, LUA_REGISTRYINDEX, idx) lua_rawgeti(L, LUA_REGISTRYINDEX, idx)
Спасибо, эти функции у меня в коде есть. Меня насторожило то, что если сохранить ссылку
Код
idx = luaL_ref(L, LUA_REGISTRYINDEX) ,
потом вытолкнуть её из стека
Код
lua_pop(L, 1),
затем попытаться вернуть
Код
lua_rawgeti(L, LUA_REGISTRYINDEX, idx) ,
то Quik падает при выполнении таких операций.
Видимо, при удалении единственной ссылки на таблицу, Lua удаляет её содержимое.
Видимо, выходом в такой ситуации будет, как Вы писали:
Код
lua_setglobal(L, "myDS");
Правда, в этом случае, придётся склеивать индивидуальное символьное имя для каждого источника данных.
Про разные потоки callback'ов и main'a знаю, но про синхронизацию доступа пока не думал. Нужно будет это учесть.
Вячеслав + написал: Рекомендую к прочтению книгу "Roberto Ierusalimschy - Programming in Lua - 2013". В своё время потратил на неё неделю, и не жалею.
Спасибо за Ваш совет, книга лежит, ждёт прочтения.
Цитата
Вячеслав + написал: lua_pushvalue как раз копирует значение
Нашёл описание: void lua_pushvalue (lua_State *L, int index); Pushes a copy of the element at the given valid index onto the stack.
Получается, нужно знать индекс элемента, который требуется положить в стек. Как же сохранить ссылку на таблицу, чтобы она "не потерялась" до конца работы программы? Или не перепуталась со ссылкой на другой источник данных.
int myfunction(lua_State * L) {
// DS = CreateDataSource ( "SPBFUT" , "RIM6" , INTERVAL_M1); // Работает
lua_getglobal(L, "CreateDataSource" );
lua_pushstring(L, "SPBFUT" );
lua_pushstring(L, "RIM6" );
lua_getglobal(L, "INTERVAL_M1" );
lua_call(L, 3 , 1 );
// результат на стеке
int DS = lua_gettop(L);
// C = DS:C( 1 ); // Не получается
lua_getfield(L, DS, "C" );
lua_pushvalue(L, DS);
lua_pushnumber(L, 1 );
lua_call(L, 2 , 1 );
// результат на стеке
int C = lua_gettop(L);
// DS: Close (); // Не получается
lua_getfield(L, DS, "Close" );
lua_pushvalue(L, DS);
lua_call(L, 1 , 0 );
// В Lua
// obj:func(param);
// это то же самое что
// obj.func (obj, param);
// как - то так
return 0 ;
}
Спасибо, заработало! Видимо, я не до конца понимаю организацию стека Lua. Правильно ли я понял, что таблица DS существует, пока указатель на неё хранится в стеке?
Вячеслав + написал: Напишите, что Вы хотите выполнить на Lua - помогу перевести на С++.
Я пытаюсь сделать следующее:
Код
DS = CreateDataSource("SPBFUT", "RIM6", INTERVAL_M1); // Работает
...
C = DS:C(1); // Не получается
...
DS:Close(); // Не получается
Таблица DS содержит всё, как должно быть: C - function Close - function _DataSource - userdata T - function V - function SetUpdateCallback - function H - function SetEmptyCallback - function L - function O - function Size - function
Да, я согласен, что во многих случаях можно обойтись возможностями LUA. Но, у меня задача - передавать данные в приложение на С. Поэтому, решено было оставить скрипт LUA пустым и все функции реализовать в DLL.
dj.lexus написал: Собственно, почему не работает, стало немного понятно. Тут нужно работать со всей метатаблицей, т.к. её методы нуждаются в ссылке не конкретный экземпляр источника данных. Но, как это сделать, ещё не ясно. Можно ли функции "Close" как нибудь подсунуть "_DataSource" - "userdata" из таблицы?
Может, не мучиться, а написать этот фрагмент на lua и всунуть его вовнутрь вашей длл?
Да, это тоже выход. А как кусок LUA кода вставить в DLL?
Собственно, почему не работает, стало немного понятно. Тут нужно работать со всей метатаблицей, т.к. её методы нуждаются в ссылке не конкретный экземпляр источника данных. Но, как это сделать, ещё не ясно. Можно ли функции "Close" как нибудь подсунуть "_DataSource" - "userdata" из таблицы?