Передача двумерных массивив в DLL и обратноК списку тем | 1 2 |
|
fiqe
16.01.2009 06:00
Наверно тут такой вопрос уже поднимался, но я не мог найти ответа. Я не совсем знаком с 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" ... int start(){ ... int n2=10; double myArray[][n2]; // вычисляем myArray Arr(n1,n2,myArray); ... Метатрейдер ломается с критической ошибкой. В прошлом успешно пользовался одномерными массивами и DLL. Скажите что не так делаю и покажите правильный код. Заранее спасибо. |
|
fiqe
16.01.2009 06:26
Пробовал так в DLL MT4_EXPFUNC void __stdcall Arr( const int n1, const int n2, double *x[]) { x[0][0]=1.0;} Всё равно краш. |
|
ZombieJesus
16.01.2009 14:36
fiqe :
Пробовал так в 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-мерный массив. И не прийдется ломать голову, как протолкнуть его из одной системы в другую. |
|
fiqe
16.01.2009 18:54
ZombieJesus :
fiqe :
Пробовал так в 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 крашит. |
|
Rosh
17.01.2009 11:12
Пожалуйста, оформляйте код, в этом случае вероятность прочтения гораздо выше. На картинке видно, как я это сделал:
|
|
ZombieJesus
17.01.2009 14:15
fiqe :
Пробовал так в 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) for(i=0;i<4;i++)x[i]=i;}// Реально массив скорей всего одномерный, забьем его числами по порядку
А вот как грамотно (http://www.find-info.ru/doc/cpp/006/variables-1.htm): 2.16. Как описывать ссылки (указатели) на двумерные массивы? Рассмотрим такую прог- (Без описания размерности массива в квадратных скобках, причем константой, не переменной, никак не обойтись) |
|
Laser
18.01.2009 23:15
Мужики. раз уж вопрос по ДЛЛ... Как Вы их отлаживаете эти замечательные библиотеки?..
|
|
ZombieJesus
20.01.2009 17:32
Laser :
Мужики. раз уж вопрос по ДЛЛ... Как Вы их отлаживаете эти замечательные библиотеки?..
Лично я, или вывожу на экран через sprintf()/MessageBox(), или через запись в файл интересующих меня переменных. Вызов функций библиотеки из MT4. |
|
Laser
21.01.2009 13:11
ZombieJesus : Laser : Мужики. раз уж вопрос по ДЛЛ... Как Вы их отлаживаете эти замечательные библиотеки?.. Лично я, или вывожу на экран через sprintf()/MessageBox(), или через запись в файл интересующих меня переменных. Вызов функций библиотеки из MT4. т.е Вы просто можете пронаблюдать как менялось состояние Вашей программы. Так? А приостановить ее выполнение? Изменить значение переменной7 |
|
ZombieJesus
21.01.2009 16:19
Laser :
т.е Вы просто можете пронаблюдать как менялось состояние Вашей программы. Так? А приостановить ее выполнение? Изменить значение переменной7 Мне никогда большего и не требовалось для отладки. |
|
fiqe
22.01.2009 03:54
Кто-нибудь покажите правильный пример передачи двумерного массива в DLL и обратно при условии что размер массива задаётся внешними параметрами в ЕА. |

