Я пытаюсь написать простую программу на MQL4, которая передает ссылку на функцию C ++ DLL по ссылке и печатает обновленное значение переменной на MQL4. Ниже приведен мой код.
Функция DLL:
void Test(int* X)
{
*X = 6;
}
Код MQL4
#import "Test.dll"void Test(int&);
#import
void OnStart()
{
int A;
Test(A);
Alert(A);
}
Но я не получаю никакого значения от функции C ++ для переменной A. Может ли кто-нибудь помочь мне, что я делаю здесь неправильно?
заранее спасибо
int TestMoreApproachesAtONCE( int *X,
int *Y,
int Z
)
{
*X = 6; // 6 assigned to a 4B-memory chunk ref'd by *X
Y = 6; // 6 assigned to a variable Y
return( Z ); // Z returned as a value passed from Caller
}
Функции, импортируемые из DLL в mql4-программу, должны обеспечивать согласование вызовов API Windows. Чтобы обеспечить такое соглашение, в исходном тексте программ, написанных на C или C ++, используйте ключевое слово
__stdcall
, который специфичен для компиляторов Microsoft (r). Это соглашение характеризуется следующим:· гость (в нашем случае это mql4-программа) должна «увидеть» прототип функции с именем (импортированной из DLL), чтобы правильно объединить параметры в стек;
· гость (в нашем случае это mql4-программа) помещает параметры в стек в обратном порядке, справа налево — в этом порядке импортируемая функция считывает переданные ей параметры;
· параметры передаются по значению, за исключением тех, которые явно передаются по ссылке (в нашем случае строки)
· импортированная функция очищает стек независимо, читая переданные ему параметры.
При описании прототипа импортируемой функции могут использоваться параметры по умолчанию.
Если соответствующая библиотека не может быть загружена, или есть запрет на использование DLL, или импортированная функция не найдена — советник прекращает свою работу с соответствующим сообщением «Эксперт остановлен» в Журнале (файл журнала). В этом случае советник не будет работать, пока не будет повторно инициализирован. Советник может быть переинициализирован в результате перекомпиляции или после открытия таблицы его свойств и нажатия кнопки ОК.
#import "Test.dll" // -----------------------------------------------
void Test( int& );
int TestMoreApproachesAtONCE( int &X,
int &Y,
int Z
);
#import // "Test.dll" // -----------------------------------------------
void OnStart()
{
int A = EMPTY,
B = EMPTY,
C = EMPTY;
// ---------------------------------------------------<PRE>
Print( " TEST:: inital values are: A = ", A,
" B = ", B,
" C = ", C
);
// ---------------------------------------------------<TEST>
C = TestMoreApproachesAtONCE( A, B, 6 );
// ---------------------------------------------------<POST>
Print( " TEST:: final values are: A = ", A,
" B = ", B,
" C = ", C
);
}
Передача параметров
Все параметры простых типов передаются по значениям, если явно не указано, что они передаются по ссылке. Когда передается строка, передается адрес буфера скопированной строки; если строка передается по ссылке, адрес буфера этой строки без копирования передается в функцию, импортированную из DLL.Структуры, которые содержат динамические массивы, строки, классы, другие сложные структуры, а также статические или динамические массивы перечисляемых объектов, не могут быть переданы в качестве параметра импортируемой функции.
При передаче массива в DLL адрес начала буфера данных всегда передается (независимо от
AS_SERIES
флаг). Функция внутри DLL ничего не знает оAS_SERIES
флаг, переданный массив является статическим массивом неопределенной длины; дополнительный параметр должен использоваться для указания размера массива.
Других решений пока нет …