MetaTrader4 переача парамтеров в dll c++

 

Имеется mt4 (build 1031), проект dll из примеров изначально не заработал, хотя проблем при компиляции не возникло. Проблемы возникают только в момент вызова функции GetRatesItemValue, на вкладке "Эксперты" в mt4 выводятся вот такие строки:

Cannot find 'GetRatesItemValue' in 'DLLSample.dll'

DLLSampleTester XAGUSD,H1: unresolved import function call

опытным путем пришел к выводу, что проблема в связке MqlRates (mql4) -> RateInfo (dll)

DLLSampleTester.mq4:

#import "DLLSample.dll"

double GetRatesItemValue( MqlRates &rates[]);

#import

...

int start()

{

MqlRates rates[];

ArrayCopyRates(rates);

GetRatesItemValue(rates);

}

DLLSample.cpp:

#pragma pack(push,1)

struct RateInfo

{

INT64             ctm;               // open date and time

double            open;              // Open price (absolute value)

double            high;              // Low price

double            low;               // High price

double            close;             // Close price

UINT64            vol;               // tick volume

INT32             spread;            // spread

UINT64            real;              // trade volume

};

#pragma pack(pop)

...

MT4_EXPFUNC double __stdcall GetRatesItemValue(const RateInfo* rates)

{

return(0.0);

}

изначально у функции GetRatesItemValue было еще 3 аргумента типа int, но от них избавился в процессе поиска причины.


Так же в целях предельного упрощения проблемного участка пробовал передавать не массив баров, а только один бар

DLLSampleTester.mq4:

#import "DLLSample.dll"

double GetRatesItemValue( MqlRates &rate);

#import

...

int start()

{

MqlRates rates[];

ArrayCopyRates(rates);

GetRatesItemValue(rates[0]);

}

DLLSample.cpp:

#pragma pack(push,1)

struct RateInfo

{

INT64             ctm;               // open date and time

double            open;              // Open price (absolute value)

double            high;              // Low price

double            low;               // High price

double            close;             // Close price

UINT64            vol;               // tick volume

INT32             spread;            // spread

UINT64            real;              // trade volume

};

#pragma pack(pop)

...

MT4_EXPFUNC double __stdcall GetRatesItemValue(const RateInfo rate)

{

return(0.0);

}

но результат все тот же.

Структура RateInfo взята из оф. документации

https://docs.mql4.com/ru/mql4changes

но тем не менее склоняюсь к проблемам с ее содержимым.

С другими функциями (без аргументов типа MqlRates) таких проблем не возникает.

В большей степени вопрос наверно адресован авторам ПО, но и, если кто-то решил эту проблему для себя, то буду рад любой помощи.

Обновленный MQL4 - Справочник MQL4
Обновленный MQL4 - Справочник MQL4
  • docs.mql4.com
Обновленный MQL4 - Справочник MQL4
 
q19:


Cannot find 'GetRatesItemValue' in 'DLLSample.dll'

DLLSampleTester XAGUSD,H1: unresolved import function call


вообще-то это говорит что в DLL-ке не нашлась означенная точка входа. Или опции компилятора/линкера не те, или DLL-ка лежит не там где должна или вообще собрана под другую архитектуру. Аргументы не входят в сигнатуру импортируемых функций, функция определяется сугубо по имени, то есть RateInfo тут ни при чём.
 
Maxim Kuznetsov:
вообще-то это говорит что в DLL-ке не нашлась означенная точка входа. Или опции компилятора/линкера не те, или DLL-ка лежит не там где должна или вообще собрана под другую архитектуру. Аргументы не входят в сигнатуру импортируемых функций, функция определяется сугубо по имени, то есть RateInfo тут ни при чём.


Если переписать функцию на работу с одним аргументом типа int не меняя имя

DLLSampleTester.mq4:

#import "DLLSample.dll"

double GetRatesItemValue(int);

#import

...

int start()

{

GetRatesItemValue(1);

}

DLLSample.cpp:

MT4_EXPFUNC double __stdcall GetRatesItemValue(const int arg)

{

return(0.0);

}

то все работает как положено.

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

Настройки проекта VS не изменялись (проект из примеров с дистрибутивом), пробовал собирать средствами VS2012 и VS2013 - разницы нет, т.ч. вероятность проблем с компилятором/линкером маловероятна.

Старый способ передачи баров через двумерный массив double работает, но в разы медленнее т.к. производит именно копирование, а не передачу по ссылки, и потому желательно заставить работать передачу MqlRates.

 
Спасибо за сообщение, мы внесли исправления в подбор имени для импортируемой из DLL функции (MSVC name mangling)

При компиляции DLL используйте DEF файл, чтобы исключить параметры из имени экспортируемой функции, такая DLL без проблем будет работать в текущем билде терминала.
Name mangling - Wikipedia
Name mangling - Wikipedia
  • en.wikipedia.org
This article is about name mangling in computer languages. For name mangling in file systems, see filename mangling. For other uses, see Name conflict. In compiler construction, name mangling (also called name decoration) is a technique used to solve various problems caused by the need to resolve unique names for programming entities in many...
 
Ilyas:
Спасибо за сообщение, мы внесли исправления в подбор имени для импортируемой из DLL функции (MSVC name mangling)

При компиляции DLL используйте DEF файл, чтобы исключить параметры из имени экспортируемой функции, такая DLL без проблем будет работать в текущем билде терминала.
Спасибо, подключение DEF-файла решило проблему. Файл уже был, но я не проверил присутствует ли он в настройках проекта, а он просто не был подключен изначально.