1

Тема: Можно ли подсунуть свою функцию C++ как main функцию скрипта lua?

Сразу извиняюсь за может несколько расплывчатую формулировку, но вся соль вот в чем:

Если посмотреть на коннектор к КВИКу QScalp'а то видим там последней строчкой код:

...

require(AgentName)

Как видно функция main напрочь отсутствует, никаких конструкций типа:

is_run = true;

function main()

while is_run do
    sleep(100)
end

end

function onClose(signal)

   is_run = false

end

однако когда жмём кнопку запустить получаем сообщение "QScalpAgent успешно запущен" и скрипт остается помеченным как запущенный.

Вопрос, как добиться такого результата на чистом C API?

Как сказано в документации, скрипт остается помеченным пока выполняется в метод main, приходят на ум 2 варианта:
1. Каким то образом на C API была написана функция которую "подсунули" как метод main;
2. Как то был перехвачен поток выполнения в котором выполняется main и уже он поставлен в ожидание;

PS: Обмолвлюсь сразу, что ничего не имею против варианта с кусочком кода на lua, но знать и понимать хочется все тонкости.

2 (2016-09-29 11:29:49 отредактировано sam063rus)

Re: Можно ли подсунуть свою функцию C++ как main функцию скрипта lua?

-

3

Re: Можно ли подсунуть свою функцию C++ как main функцию скрипта lua?

А вот он!

-----------------------------------------------------------------------------
--  QScalpAgent for QUIK (c) 2014 Nikolay Moroshkin, http://www.qscalp.ru  --
-----------------------------------------------------------------------------

AgentName = "QScalpAgent"

CommandBuffer = 4096

SecListBuffer = 4096
AccListBuffer = 4096
HistoryBuffer = 262144

MaxStockDepth = 170
DealsQueueDepth = 4519
AuxInfoQueueDepth = 85

TraderBuffer = 4096
TraderQueueDepth = 520

StopOrderExpire = "TODAY"

LogAppend = false

CList = { "CETS", "FEC", "FEE", "FEF", "FEG", "FEM", "FEN", "FEO",
  "FEP", "FEV", "FEX", "FUTUX", "GTS", "GTSST", "INDX", "QJSIM",
  "RTSIDX", "RTSIND", "SPBFUT", "TQBR", "UCED", "UCRTS", "UCSI" }

-----------------------------------------------------------------------------

package.path = ""
package.cpath = getScriptPath() .. "\\" .. AgentName .. ".dll"

require(AgentName)

-----------------------------------------------------------------------------

Так, то что это колбэк это стало понятно, теперь вопрос, как подписаться на этот колбек в C++ dll?

4 (2016-09-29 11:29:57 отредактировано sam063rus)

Re: Можно ли подсунуть свою функцию C++ как main функцию скрипта lua?

-

5

Re: Можно ли подсунуть свою функцию C++ как main функцию скрипта lua?

sam063rus пишет:

это не то - я не про это
тот файл, что нам нужен - называется у Морошкина: QScalpAgent.dll. там, в основном, всё написано, что вас интересует.

А! Так, этот файл же на плюсах написан, к сожалению как его декомпилить я не знаю, т.к. с C++ как не довелось познакомиться настолько близко. Прошелся только по нему Dependency walker'ом, как и ожидал увидел там luaopen_QScalpAgent() и всё.

6

Re: Можно ли подсунуть свою функцию C++ как main функцию скрипта lua?

sam063rus пишет:

это не то - я не про это
тот файл, что нам нужен - называется у Морошкина: QScalpAgent.dll. там, в основном, всё написано, что вас интересует.

для начала, вот ещё посмотрите: http://forum.quik.ru/messages/forum10/m … essage1501

Перед тем как писать сюда прочитал всю эту тему. Ок, еще раз подробнее посмотрю на pushcclosure().

7 (2016-09-29 11:30:08 отредактировано sam063rus)

Re: Можно ли подсунуть свою функцию C++ как main функцию скрипта lua?

-

8 (2016-09-29 11:30:18 отредактировано sam063rus)

Re: Можно ли подсунуть свою функцию C++ как main функцию скрипта lua?

-

9 (2015-03-17 00:47:49 отредактировано xpoftik)

Re: Можно ли подсунуть свою функцию C++ как main функцию скрипта lua?

Да, всё получилось! Если функцию зарегистрировать в глобальных, то она будет вызываться КВИКом как колбэк, в случае совпадения идентификатора конечно!
Круто! :)

Кому интересно вот экспериментальный код:

//Функция бросает сообщение в КВИКе, её будем регистрировать как main
static int forLua_LuaMessage(lua_State* L){
    lua_getglobal(L, "message");
    lua_pushfstring(L, "Main!");
    lua_pcall(L, 1, 0, 0);

    return 0;
}

...


extern "C" LUALIB_API int luaopen_testQUIKCOnnector(lua_State* L) {
    luaL_openlib(L, "testQUIKCOnnector", ls_lib, 0);
    
    //Заталкиваем функцию в стек
    lua_pushcclosure(L, forLua_LuaMessage, 0);
    //Регистрируем её как колбэк на main
    lua_setfield(L, LUA_GLOBALSINDEX, "main");
     
    return 0;
}