Пробовал так в DLL
MT4_EXPFUNC void __stdcall Arr( const int n1, const int n2, double *x[])
{ x[0][0]=1.0;}
Всё равно краш.
Пробовал так в DLL
MT4_EXPFUNC void __stdcall Arr( const int n1, const int n2, double *x[])
{ x[0][0]=1.0;}
Всё равно краш.
ИМХО, указатель надо просто передавать на "double", без всяких скобок и "указателей на указатель". Поскольку всякий многомерный массив на самом деле одномерный, по крайней мере в Си. :)
Мне ни разу не приходилось делать таких вещей, чтоб нужно было передавать из MT4 массивы размерности больше единицы (если нужна действительно сложная обработка, она выносится целиком в DLL, где происходит раз в 10 быстрее, чем в MQL4), но появись нужда в 2D-массиве между MT4 и DLL, я бы обошелся одномерным, адресуясь в нем так: x[n2*posX+posY], где "n2" - размерность массива по оси Y (второму индексу), posX и posY - соотрественно первый и второй индексы. Можно и наоборот, адресоваться по первой размерности: x[n1*posY+posX]. Главное, использовать везде одинаковый формат обращения (по какой размерности обрабатывать массив). При необходимости, тем же путем можно сделать хоть 10-мерный массив. И не прийдется ломать голову, как протолкнуть его из одной системы в другую.
Пробовал так в DLL
MT4_EXPFUNC void __stdcall Arr( const int n1, const int n2, double *x[])
{ x[0][0]=1.0;}
Всё равно краш.
ИМХО, указатель надо просто передавать на "double", без всяких скобок и "указателей на указатель". Поскольку всякий многомерный массив на самом деле одномерный, по крайней мере в Си. :)
Мне ни разу не приходилось делать таких вещей, чтоб нужно было передавать из MT4 массивы размерности больше единицы (если нужна действительно сложная обработка, она выносится целиком в DLL, где происходит раз в 10 быстрее, чем в MQL4), но появись нужда в 2D-массиве между MT4 и DLL, я бы обошелся одномерным, адресуясь в нем так: x[n2*posX+posY], где "n2" - размерность массива по оси Y (второму индексу), posX и posY - соотрественно первый и второй индексы. Можно и наоборот, адресоваться по первой размерности: x[n1*posY+posX]. Главное, использовать везде одинаковый формат обращения (по какой размерности обрабатывать массив). При необходимости, тем же путем можно сделать хоть 10-мерный массив. И не прийдется ломать голову, как протолкнуть его из одной системы в другую.
Спасибо за ответ. В крайнем случае прибегу к вашим рекомендациям.
Пробовал так в DLL
MT4_EXPFUNC void __stdcall Arr( const int n1, const int n2, double *x)
{ x[0][0]=1.0;}
MSVC даёт ошибку
error: expression must have pointer-to-object type in x[0][0]=1.0;
Апдейт: После долгих поисков на инете, я заключил что есть три основных способа передачи двумерных массивов в DLL функции:
1. void Arr( const int n1, const int n2, double **x) - вызывает краш метатрейдера
2. void Arr( const int n1, const int n2, double *x[]) - вызывает краш метатрейдера
3. void Arr( const int n1, const int n2, double *x[100]) - ещё не пробовал, но это будет не самым елегантным решением так как размеры массива у меня задаются в эксперте
Уважаемые программисты, пожалуйста посмотрите на мое первое сообщение и скажите почему MetaTraider крашит.
Пожалуйста, оформляйте код, в этом случае вероятность прочтения гораздо выше. На картинке видно, как я это сделал:
Пробовал так в DLL
MT4_EXPFUNC void __stdcall Arr( const int n1, const int n2, double *x)
{ x[0][0]=1.0;}
MSVC даёт ошибку
error: expression must have pointer-to-object type in x[0][0]=1.0;
Апдейт: После долгих поисков на инете, я заключил что есть три основных способа передачи двумерных массивов в DLL функции:
1. void Arr( const int n1, const int n2, double **x) - вызывает краш метатрейдера
2. void Arr( const int n1, const int n2, double *x[]) - вызывает краш метатрейдера
3. void Arr( const int n1, const int n2, double *x[100]) - ещё не пробовал, но это будет не самым елегантным решением так как размеры массива у меня задаются в эксперте
Уважаемые программисты, пожалуйста посмотрите на мое первое сообщение и скажите почему MetaTraider крашит.
Без задания размерности массива в DLL (а она в вышеприведенной функции никак не задается, выражение "double *x" с размерностями вообще не связано, это просто указатель на данные соответсвующего типа. Сколько их, и какой размерности, его не касается) к массиву в принципе невозможно корректно обратиться! Что касается примеров 1,2 и 3, в них всех вообще-то подразумевается, что массив сложный - указатель на массив указателей(!), уже каждый из которых указывает на числа. Это имеет смысл только если в строках или столбцах количество чисел различается (это количество должно храниться в отдельном массиве/структуре) и видимо не соответсвует простой модели в МТ (размерности всех строк и всех столбцов одинаковы), из-за такого грубого несоответсвия типов странно было бы, если бы МТ не падал. Проверь так:
MT4_EXPFUNC void __stdcall Arr( const int n1, const int n2, double *x)
{int i;
for(i=0;i<4;i++)x[i]=i;}// Реально массив скорей всего одномерный, забьем его числами по порядку
В mql4 такой код:
...
#import "Arr.dll"
void Arr(int n1, int n2, double x[]);
#import
...
int start(){
...
double myArray[2][2];
// вычисляем myArray
Arr(n1,n2,myArray);
Alert(myArray[0][0]+" "+myArray[0][1]+" "+myArray[1][0]+" "+myArray[1][1]);// выведем, что получилось в массиве
А вот как грамотно (http://www.find-info.ru/doc/cpp/006/variables-1.htm):
2.16. Как описывать ссылки (указатели) на двумерные массивы? Рассмотрим такую прог-
рамму:
#include <stdio.h>
#define First 3
#define Second 5
char arr[First][Second] = {
"ABC.",
{ 'D', 'E', 'F', '?', '\0' },
{ 'G', 'H', 'Z', '!', '\0' }
};
char (*ptr)[Second];
main(){
int i;
ptr = arr; /* arr и ptr теперь взаимозаменимы */
for(i=0; i < First; i++)
printf("%s\t%s\t%c\n", arr[i], ptr[i], ptr[i][2]);
}
Указателем здесь является ptr. Отметим, что у него задана размерность по второму
измерению: Second, именно для того, чтобы компилятор мог правильно вычислить двумер-
ные индексы.
Попробуйте сами объявить
char (*ptr)[4];
char (*ptr)[6];
char **ptr;
и увидеть, к каким невеселым эффектам это приведет (компилятор, кстати, будет
ругаться; но есть вероятность, что он все же странслирует это для вас. Но работать
оно будет плачевно). Попробуйте также использовать ptr[x][y].
(Без описания размерности массива в квадратных скобках, причем константой, не переменной, никак не обойтись)
Лично я, или вывожу на экран через sprintf()/MessageBox(), или через запись в файл интересующих меня переменных. Вызов функций библиотеки из MT4.
Лично я, или вывожу на экран через sprintf()/MessageBox(), или через запись в файл интересующих меня переменных. Вызов функций библиотеки из MT4.
т.е Вы просто можете пронаблюдать как менялось состояние Вашей программы. Так? А приостановить ее выполнение? Изменить значение переменной7
Мне никогда большего и не требовалось для отладки.
Кто-нибудь покажите правильный пример передачи двумерного массива в DLL и обратно при условии что размер массива задаётся внешними параметрами в ЕА.
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Наверно тут такой вопрос уже поднимался, но я не мог найти ответа. Я не совсем знаком с mql4 и c++, поэтому будет благодарен ответам показывющим как правильно поступить в моём случае. Итак, DLL функция проста:
MT4_EXPFUNC void __stdcall Arr( const int n1, const int n2, double ** x)
{ x[0][0]=1.0;}
В mql4 такой код:
...
#import "Arr.dll"
void Arr(int n1, int n2, double x[][]);
#import
...
int start(){
...
int n2=10;
double myArray[][n2];
// вычисляем myArray
Arr(n1,n2,myArray);
...
Метатрейдер ломается с критической ошибкой. В прошлом успешно пользовался одномерными массивами и DLL. Скажите что не так делаю и покажите правильный код. Заранее спасибо.