Сохранение состояние между вызовами функций из DLL

 

Приветствую всех.

Дело вот в чем. К сожалению, брокеров, предлагающих MT5 крайне мало, и приходится юзать MT4.

Ограниченные возможности языка mql4 заставили меня попробовать перенести весь код на c++ в dll.

Я хотел сделать ООП-управление сделками, наподобие api->openOrder (...) полностью из dll. Но сложные объекты между mql и dll передавать, естественно, нельзя.

Это и не было особой проблемой, ибо можно вызывать какую-либо функцию из dll во время каждого тика, в функции start (). И в нее передавать текущие цены, бары и тп.

НО. Проблема возникла при подаче команд mql стороне из dll. Команды могут быть совершенно разного формата, например, на изменение стоп-лосса по нескольким разным ордерам, закрытие всех ордеров, открытие и т.д.

Единственное, что точно будет работать и до чего я додумался, это передача на mql сторону строкового массива с инфой.

К примеру, в нулевом элементе содержится тип текущей команды, а дальше уже его структура может отличаться в зависимости от команды.

Но это будет как-то геморно парсить в mql этот массив.

Но dll не сохраняет свое состояние между вызовами. То есть, если изменить значение переменной в dll, то при следующем вызове, оно останется прежним. Даже при использовании указателей.

Если бы объект из dll постоянно висел в памяти, можно было сделать что-то вроде:

if (текущая команда == изменить стопы)

{

double[] stops = getStopsFromDll ();

}

И не пришлось бы парсить массив.

Но вот беда. Для dll все как в первый раз. Как сохранять состояние хоть каких-нибудь объектов внутри dll между вызовами функций?

 
Buhach:

Ограниченные возможности языка mql4 заставили меня попробовать перенести весь код на c++ в dll.

Возможности скоро будут практически такие же как в МТ5.
 
TheXpert:
Возможности скоро будут практически такие же как в МТ5.

Это замечательно, но мне надо прямо сейчас
 
TheXpert:
скоро

Не доверяю я этим "скоро". Это как php 6.0 уже 10 лет обещают с минуты на минуту выпустить.
 
Чтобы сохраняла, надо создать объект в секции init, передать его преобразованный к типу, например int, манипулятор в mql-код, оттуда обращаться к объекту по этому манипулятору, а в конце работы в секции deinit объект ликвидировать и освободить манипулятор. Понятно, что что при таком подходе чем больше логики и расчётов запихнуть в библиотеку (и тем самым привязать к одному манипулятору), тем лучше. Что будет происходить внутри библиотеки - mql-код никоим образом не колышет. :)))
 
alexjou:
Чтобы сохраняла, надо создать объект в секции init, передать его преобразованный к типу, например int, манипулятор в mql-код, оттуда обращаться к объекту по этому манипулятору, а в конце работы в секции deinit объект ликвидировать и освободить манипулятор. Понятно, что что при таком подходе чем больше логики и расчётов запихнуть в библиотеку (и тем самым привязать к одному манипулятору), тем лучше. Что будет происходить внутри библиотеки - mql-код никоим образом не колышет. :)))


Что вы имеете ввиду под "манипулятором"? Это типа как вызывать в mql-функции start () какую-либо dll-функцию, из нее получать переменную, типа, скажем, int.

А дальше

if (int = 0) делаем то-то

if (int = 1) делаем то-то

if (int = 2) делаем то-то

?

Если так, то передачей лишь ТИПА команды, дело не ограничивается. Нужно еще и инфу различного формата туда-сюда гонять.

"создать объект в секции init" - где создать объект? Я имею ввиду сложные C++ объекты, для этого и затеял всю эту затею.

 
Buhach:

Приветствую всех.

Дело вот в чем. К сожалению, брокеров, предлагающих MT5 крайне мало, и приходится юзать MT4.

Ограниченные возможности языка mql4 заставили меня попробовать перенести весь код на c++ в dll.

Я хотел сделать ООП-управление сделками, наподобие api->openOrder (...) полностью из dll. Но сложные объекты между mql и dll передавать, естественно, нельзя.

Это и не было особой проблемой, ибо можно вызывать какую-либо функцию из dll во время каждого тика, в функции start (). И в нее передавать текущие цены, бары и тп.

НО. Проблема возникла при подаче команд mql стороне из dll. Команды могут быть совершенно разного формата, например, на изменение стоп-лосса по нескольким разным ордерам, закрытие всех ордеров, открытие и т.д.

Единственное, что точно будет работать и до чего я додумался, это передача на mql сторону строкового массива с инфой.

К примеру, в нулевом элементе содержится тип текущей команды, а дальше уже его структура может отличаться в зависимости от команды.

Но это будет как-то геморно парсить в mql этот массив.

Но dll не сохраняет свое состояние между вызовами. То есть, если изменить значение переменной в dll, то при следующем вызове, оно останется прежним. Даже при использовании указателей.

Если бы объект из dll постоянно висел в памяти, можно было сделать что-то вроде:

if (текущая команда == изменить стопы)

{

double[] stops = getStopsFromDll ();

}

И не пришлось бы парсить массив.

Но вот беда. Для dll все как в первый раз. Как сохранять состояние хоть каких-нибудь объектов внутри dll между вызовами функций?

Про строки надо забыть.

У меня всё сохраняет в DLL. Проблем не было. Код покажите, как делаете.

 
Zhunko:

Про строки надо забыть.

У меня всё сохраняет в DLL. Проблем не было. Код покажите, как делаете.


Ну например так.

Всегда "Ноль" показывает

int value = 0;

/**
 * Вернуть текущее состояние - тестим сохранение значений между вызовами
 */
MT4_EXPFUNC char* __stdcall getCurrentState ()
{
        if (value == 0)
        {
                return ("Ноль");
                value  = 1;
        }
        else
                return ("Не ноль");
}
 
Buhach:


Ну например так.

Всегда "Ноль" показывает

Этот вызов из скрипта или эксперта?

Ещё DLLMain() покажите.

 
Zhunko:

Этот вызов из скрипта или эксперта?

Ещё DLLMain() покажите.


По синтаксису ясно видно, что это в dll.

Какое значение имеет DllMain? Это вообще необязательная опциональная функция.

Можно в проекте ее указывать или не указывать, это ничего не меняет.

Странно, что у вас сохраняются значения переменных между вызовами функций dll. Покажите код, буду очень признателен

 
Проблема оказалась банальна и по моей вине. Дело ведь в том, что все, что после return уже не выполняется в c++. Поэтому и сброс значения не происходил. Поставил выше ретерна и все заработало. Значения сохраняются между вызовами. Все просто...
Причина обращения: