Переносим алгоритм советника в DLL - страница 2

 
jartmailru:
Ну вот не надо
"Пробовал. Объявлял, как там.".
.
Компилите ТОТ проект как он есть- проверяете.

ОК. Значит проект не открывается... Создаем новый проект DLL, подключаем туда ExpertSample.cpp, StdAfx.h.
Компилируем его и копируем ExpertSample.dll в \experts\libraries\
Далее копируем sampledll.mqh в \experts\include\
В теле тестового индикатора пишем:
...
#include <sampledll.mqh>
...
int start()
{
int Start = Bars-IndicatorCounted()-1;


for(int pos=Start; pos>=0; pos--)
Data[pos] = GetDoubleValue(0.0002);
// Data[pos] = 0.0001;
// Data[pos] = GetZero();


return(0);
}

Data[pos] = GetDoubleValue(0.0002); - НЕ РАБОТАЕТ.
Data[pos] = 0.0001; - РАБОТАЕТ
Data[pos] = GetZero(); - РАБОТАЕТ

в чем же дело? черт, может Borland C++ установить и в нем DLL сделать

 
jartmailru:
def- файл надо.
.
PS: а я бы скачал более старую студию.
Потому что если примеры не работают- то это странно...

Я не нашел, куда его приткнуть. Если создавать проект с нуля, то он не содержит никаких def-файлов. И в компиляции он не участвует.
Попробую поискать другие версии компилятора. Может Borland C++.
Вообще странно. Обычная DLL. Обычные вызовы. Должно работать.
 
В комплекте с MT4 проект на MS VS 6. Он нормально открывается в VS2010 и студия предлагает его переконвертировать в формат VS2010. Открывать, вроде бы, надо .dsw. Сам не раз конвертацию делал.
 

GetZero работает, если его определить, как

extern "C" __declspec (dllexport) double GetZero();

Любые другие определения типа

extern __declspec (dllexport) double GetZero();
__declspec (dllexport) double __stdcall GetZero();

и пр. формируют такую ошибку в логе:

12:05:23 Compiling 'dll_test'
12:05:24 dll_test EURUSD,H1: loaded successfully
12:05:24 dll_test EURUSD,H1: initialized
12:05:24 dll_test EURUSD,H1: cannot call function 'GetZero' from dll 'TendAnalyzer.dll' (error 127)
12:05:24 dll_test EURUSD,H1: expert stopped
12:05:25 dll_test EURUSD,H1: deinitialized
12:05:25 dll_test EURUSD,H1: uninit reason 1
12:05:25 dll_test EURUSD,H1: removed

Аналогичная ошибка при загрузке тестового проекта

11:47:01 Compiling 'dll_test'
11:47:02 dll_test EURUSD,H1: loaded successfully
11:47:02 dll_test EURUSD,H1: initialized
11:47:02 dll_test EURUSD,H1: cannot call function 'GetDoubleValue' from dll 'ExpertSample.dll' (error 127)
11:47:02 dll_test EURUSD,H1: expert stopped
11:57:22 dll_test EURUSD,H1: deinitialized
11:57:22 dll_test EURUSD,H1: uninit reason 1
 
Daniil:
В комплекте с MT4 проект на MS VS 6. Он нормально открывается в VS2010 и студия предлагает его переконвертировать в формат VS2010. Открывать, вроде бы, надо .dsw. Сам не раз конвертацию делал.

VS2010 ругается, что не удается загрузить ExpertSample.dsp и предлагает его удалить из проекта.
Если открывать ExpertSample.dsp, то говорит, что надо преобразовать проект. После преобразования открывается пустой проект - ни каких файлов в нем нет. В общем фигня какая то...
 
andreybs:

GetZero работает, если его определить, как

extern "C" __declspec (dllexport) double GetZero();


работает, потому что это единственно верное объявление. Соответственно, и вторая функция должна быть объявлена таким же образом.

Прикрепите код cpp и mql, яснее станет, что вы не так делаете. А делаете что-то не так точно, потому что у всех работает, значит и у вас должно.

 
alsu:

работает, потому что это единственно верное объявление. Соответственно, и вторая функция должна быть объявлена таким же образом.

Хотелось бы верить... Только народ настаивает на использовании __stdcall после которого перестает работать даже GetZero.


alsu:
Прикрепите код cpp и mql, яснее станет, что вы не так делаете. А делаете что-то не так точно, потому что у всех работает, значит и у вас должно.

Прикрепил архив со всеми файлами.
Файлы:
dll_test.zip  16 kb
 
Если запустить DLL из архива, то при вызове GetZero все работает, а при вызове GetValue терминал крашится (закрывается и не выдает ошибок).
 
Попробовал другой компилятор - С++ Builder 2007. Он собрал DLL в 2 раза легче, чем VC. Но новая DLL вообще не позволяет вызвать ни одной функции (делал по-разному, в т.ч. и как в примере).

На этот раз в логе терминала появилась новая ошибка:
14:31:36 Compiling 'dll_test'
14:31:36 dll_test EURUSD,H1: loaded successfully
14:31:36 dll_test EURUSD,H1: initialized
14:31:36 dll_test EURUSD,H1: cannot load library 'TendAnalyzer.dll' (error 126)
14:31:36 dll_test EURUSD,H1: expert stopped
14:36:41 dll_test EURUSD,H1: deinitialized
14:36:41 dll_test EURUSD,H1: uninit reason 1
14:36:41 dll_test EURUSD,H1: removed
 

Нашел такую тему https://forum.mql4.com/ru/10657

Проблема в специфическом объявлении функции для компилятора. При построении DLL, экспортируемое имя искажается. Так вот, в компиляторе C++ Builder экспорт функций

extern "C" double __declspec(dllexport)__stdcall GetDouble(double val)
extern "C" double __declspec(dllexport) __stdcall GetZero()

не искажает экспортируемых названий, а компилятор VC++ экспортирует их как _GetDouble@8 и _GetZero@0 соответственно.

Мне удалось запустить DLL, скомпилированную в C++ Builder, а вот VC++ никак. Для VC++ нужно как то иначе делать объявление функций. Я пока не понял, как.

Причина обращения: