Не раз сталкивался с тем, что вместе с советником на MQL прилагалась библиотека DLL. Мне стало интересно подробнее узнать обо всем этом.
Сначала я нашел очень интересное видео-руководство по написанию DLL в среде Embarcadero Rad Studio C++Builder. Этот вопрос заинтересовал меня вдвойне, т.к. у меня был небольшой опыт разработки в C++Builder 6. У меня до сих пор сохранился на диске этот компилятор. По аналогии с представленным ниже видео я и собрал свою первую DLL в C++Builder 6.
Для желающих более углубленно изучить этот процесс представляю следующие материалы:
Запускаем C++ Builder, переходим меню File->New->Other
Нужный нам пункт указан на картинке, выбираем его.
Жмем “ОК”, 50% дела сделано
Откроется новое окно, в котором уже будет “заготовка” нашей будущей DLL.
Со следующим кодом:
/---------------------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
//---------------------------------------------------------------------------
// Important note about DLL memory management when your DLL uses the
// static version of the RunTime Library:
//
// If your DLL exports any functions that pass String objects (or structs/
// classes containing nested Strings) as parameter or function results,
// you will need to add the library MEMMGR.LIB to both the DLL project and
// any other projects that use the DLL. You will also need to use MEMMGR.LIB
// if any other projects which use the DLL will be performing new or delete
// operations on any non-TObject-derived classes which are exported from the
// DLL. Adding MEMMGR.LIB to your project will change the DLL and its calling
// EXE's to use the BORLNDMM.DLL as their memory manager. In these cases,
// the file BORLNDMM.DLL should be deployed along with your DLL.
//
// To avoid using BORLNDMM.DLL, pass string information using "char *" or
// ShortString parameters.
//
// If your DLL uses the dynamic version of the RTL, you do not need to
// explicitly add MEMMGR.LIB as this will be done implicitly for you
//---------------------------------------------------------------------------
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
Комментарии можно убрать и добавим свою функцию. Мы будем передавать в DLL два целых числа, а в ответ получим их произведение. Вот такой простой пример, который показывает как легко передавать и получать данные из DLL в MQL4.
Добавим свою функцию
//---------------------------------------------------------------------------
#include <vcl.h>
#include <windows.h>
#pragma hdrstop
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
//---------------------------------------------------------------------------
extern "C" __declspec(dllexport) int test(int x, int y)
{
return (x*y); //вернем из нашей функции произведение переменных X и Y
}
//---------------------------------------------------------------------------
Особое внимание нужно уделить макрокоманде, которая идет перед объявлением функции. Благодаря ей, мы получаем возможность работать с функциями внутри DLL.
extern "C" __declspec(dllexport)
Теперь настроим среду и можем собирать нашу библиотеку.
Переходим в меню Project->Options и убираем галочки из двух пунктов:
C++ Linker-> Link with Dinamic RTL
Packages-> Link with runtime packages
Компилируем наш проект нажатием кнопки Run — F9 или на зеленый треугольник. После компиляции выскакивает следующая надпись:
Далее просто жмем ОК. Следовать данным рекомендациям нам не нужно т.к. мы не связываем нашу DLL с исполняемым файлом *.exe.
Сейчас можно проверить, как она работает в паре с Metatrader 4. Для удобства, я предпочитаю закидывать DLL сразу в C:\Windows\System32, тогда нет нужды тягать ее с собой по всем терминалам на одной ОС.
Рассмотрим как подключить DLL к программе на MQL4.
Для этого в MetaEditor терминала создадим советник с именем TestDLL.
//+------------------------------------------------------------------+
//| TestDLL.mq4 |
//| Copyright 2015, AM2 |
//| http://www.forexsystems.biz |
//+------------------------------------------------------------------+
#property copyright "Copyright 2015, AM2"
#property link "http://www.forexsystems.biz"
#property version "1.00"
#property strict
#import "Project2.dll" // подключаем нашу DLL
int _test(int x,int y); //функция из нашей DLL
#import
extern int x=5;
extern int y=7;
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int OnInit()
{
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void OnTick()
{
Comment("\n",x," * ",y," = ",_test(x,y));
}
//+------------------------------------------------------------------+
Внимание, функция:
test(int x,int y)
Из нашей DLL в коде MQL4 вызывается через подчеркивание “_”
Скромное пояснение.
Когда убираем галочки с «Use Dinamic RTL» и «Build with runtime packages», то после компиляции файл будет весить больше, но запускаться будет на любой машине, т.к. в него будут включены все исполняемые компоненты.
Редактирован: 24 августа 2021, 20:56
Комментарии (1)
Когда убираем галочки с «Use Dinamic RTL» и «Build with runtime packages», то после компиляции файл будет весить больше, но запускаться будет на любой машине, т.к. в него будут включены все исполняемые компоненты. Редактирован: 24 августа 2021, 20:56
24 ShamanHand Сообщений: 1092 - Наношу добро, причиняю пользу.
Зарегистрируйтесь или авторизуйтесь, чтобы оставить комментарий