a1exb:
Опять же - нужен код (MQL5 и С++). Также нужно заметить, что ворнинги вовсе не безобидные: там речь о приведении указателей на double к числу int. Это достаточно серьезно.
Только ворнинги по типу
Подскажите пожалуйста что я делаю не так?
Ihor Herasko:
Опять же - нужен код (MQL5 и С++). Также нужно заметить, что ворнинги вовсе не безобидные: там речь о приведении указателей на double к числу int. Это достаточно серьезно.
Я сейчас с телефона и кода под рукой нет. Но он есть в статье, которую я указал в начале. Я его не менял, компилировал пустой dll проект в студии под х64.
Опять же - нужен код (MQL5 и С++). Также нужно заметить, что ворнинги вовсе не безобидные: там речь о приведении указателей на double к числу int. Это достаточно серьезно.
Ihor Herasko:
Опять же - нужен код (MQL5 и С++). Также нужно заметить, что ворнинги вовсе не безобидные: там речь о приведении указателей на double к числу int. Это достаточно серьезно.
Опять же - нужен код (MQL5 и С++). Также нужно заметить, что ворнинги вовсе не безобидные: там речь о приведении указателей на double к числу int. Это достаточно серьезно.
DLL:
extern "C" __declspec(dllexport) int __stdcall GetPtr(double *a) { return((int)a); } extern "C" __declspec(dllexport) double __stdcall GetValue(int pointer,int i) { return(((double*) pointer)[i]); } extern "C" __declspec(dllexport) void __stdcall SetValue(int pointer,int i,double value) { ((double*) pointer)[i]=value;
Работа с длл:
#import "IndEx.dll" int GetPtr(double &a[]); double GetValue(int pointer,int i); void SetValue(int pointer,int i,double value); #import //+------------------------------------------------------------------+ //| зарегистрировать буфер | //+------------------------------------------------------------------+ void RegisterBuffer(double &Buffer[],string name,int mode) export { UnregisterBuffer(Buffer); //сначала удалим на всякий случай переменную int direction=0; if(ArrayGetAsSeries(Buffer)) direction=1; //устанавливаем флаг направления индексации name=name+"#"+IntegerToString(mode)+"#"+Symbol()+"#"+IntegerToString(Period())+ "#"+IntegerToString(ArraySize(Buffer))+"#"+IntegerToString(direction); int ptr=GetPtr(Buffer); //вытаскиваем указатель if(ptr==0) return; MathSrand(ptr); //очень удобно использовать значение указателя (а не время) для инициализации ГПСЧ while(true) { int rnd=MathRand(); if(!GlobalVariableCheck(name+"#"+IntegerToString(rnd))) //обеспечим уникальность - полагаем, что вряд ли кому придет в голову { //исследовать больше, чем RAND_MAX буферов:) name=name+"#"+IntegerToString(rnd); GlobalVariableSet(name,ptr); //ну и записываем в глобальные break; } } } //+------------------------------------------------------------------+ //| снять регистрацию буфера | //+------------------------------------------------------------------+ void UnregisterBuffer(double &Buffer[]) export { int ptr=GetPtr(Buffer); //будем разрегистрироваться по фактическому адресу буфера if(ptr==0) return; int gt=GlobalVariablesTotal(); int i; for(i=gt-1;i>=0;i--) //просто перебрать все глобальные переменные { //и удалить наш буфер отовсюду, где он "засветился" string name=GlobalVariableName(i); if(GlobalVariableGet(name)==ptr) GlobalVariableDel(name); } } //+------------------------------------------------------------------+ //| найти буфер | //+------------------------------------------------------------------+ int FindBuffers(string name,int mode,string symbol,int period,string &buffers[]) export { int count=0; int i; bool found; string name_i; string descriptor[]; int gt=GlobalVariablesTotal(); StringTrimLeft(name); //обрезать строку от лишних пробелов StringTrimRight(name); ArrayResize(buffers,count); //обнулить размер for(i=gt-1;i>=0;i--) { found=true; name_i=GlobalVariableName(i); StringExplode(name_i,"#",descriptor); //разбить строку на поля if(ArraySize(descriptor)<4) continue; if(StringFind(descriptor[0],name)<0 && name!=NULL) found=false; //проверяем каждое поле на соответствие критерию поиска if(((int)descriptor[1]!=mode) && (mode>=0)) found=false; if((descriptor[2]!=symbol) && (symbol!=NULL)) found=false; if(((int)descriptor[3]!=period) && (period>0)) found=false; if(found) { count++; //все условия сошлись, заносим в список ArrayResize(buffers,count); buffers[count-1]=name_i; } } return(count); } //+------------------------------------------------------------------+ //| получить значение индикатора по дескриптору и индексу | //+------------------------------------------------------------------+ double GetIndicatorValue(string descriptor,int shift) export { int ptr; string fields[]; int size,direction; if(GlobalVariableCheck(descriptor)>0) //убедились в валидности дескриптора { ptr=(int)GlobalVariableGet(descriptor); //получили значение указателя if(ptr!=0) { StringExplode(descriptor,"#",fields); //разбили имя дескриптора на поля if(ArraySize(fields)<4) return EMPTY_VALUE; size=(int)(fields[4]); //нам нужен текущий размер массива direction=(int)(fields[5]); if(direction==1) shift=size-1-shift; //если индексация с конца if(shift>=0&&shift<size) //проверка правильности индекса - чтобы не уронить терминал return(GetValue(MathAbs(ptr),shift)); //добро, возвращаем значение } } return(EMPTY_VALUE); //в противном случае извиняйте... } //+------------------------------------------------------------------+ //| установить значение для индикатора по индексу | //+------------------------------------------------------------------+ bool SetIndicatorValue(string descriptor,int shift,double value) export { int ptr; string fields[]; int size,direction; if(GlobalVariableCheck(descriptor)>0) //убедились в валидности дескриптора { ptr=(int)GlobalVariableGet(descriptor); //получили значение указателя if(ptr!=0) { StringExplode(descriptor,"#",fields); //разбили имя дескриптора на поля if(ArraySize(fields)<4) return false; size=(int)(fields[4]); //нам нужен текущий размер массива direction=(int)(fields[5]); if(direction==1) shift=size-1-shift; //если индексация с конца if(shift>=0&&shift<size) //проверка правильности индекса - чтобы не уронить терминал { SetValue(MathAbs(ptr),shift,value); return(true); } } } return(false); } //+------------------------------------------------------------------+ //| разделить строку на подстроки в массив | //+------------------------------------------------------------------+ void StringExplode(string s,string separator,string &result[]) { int i,pos; ArrayResize(result,1); pos=StringFind(s,separator); if(pos<0) {result[0]=s;return;} for(i=0;;i++) { pos=StringFind(s,separator); if(pos>=0) { result[i]=StringSubstr(s,0,pos); s=StringSubstr(s,pos+StringLen(separator)); } else break; ArrayResize(result,ArraySize(result)+1); } } //+------------------------------------------------------------------+
Вызов из-за которого крашится:
... found=FindBuffers("AC_DN_Signal",0,_Symbol,_Period,import_bufs); if(found>0) import_ACDNbuf=import_bufs[0]; else import_ACDNbuf=NULL; ... if(import_ACDNbuf!=NULL) { double tmp_sig=GetIndicatorValue(import_ACDNbuf,0); ... }
Для x64 в дллке все int надо заменить на long
Комбинатор:
Для x64 в дллке все int надо заменить на long
Для x64 в дллке все int надо заменить на long
Не помогло =(
Я может как-то не так сделал? Исправил все инт на лонг, перекомпили под х64, скопировал свежую длл в папку МТ, но при импорте все равно отображается как инт. ДЛЛ точно свежая, а не старая.
UPD: этот вопрос решил, поменяв инт на лонг в exchng.mq5 в описании импорта функций длл (это самый длинный исходник в начале темы)
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Приветствую.
Появилась потребность в обмене даннымим между индикаторами. Гугл привел к
https://www.mql5.com/ru/articles/19
Регистрация данных в глоб. переменных проходит норм.
А вот при попытке чтения с помощью GetIndicatorValue - краш.
Я перекомпили под х64 в студии, ошибок нет. Только ворнинги по типу
Подскажите пожалуйста что я делаю не так?
Думал, что индекс элемента выходит за пределы (хотя это по идее быть не должно, т..к выход проверяется в самой GetIndicatorValue ), читал всегда 0 элемент - все равно краш.
Может есть какие-то отличия в чтении между х86 и х64?
---
MT5 5.0 build 1375
Visual studio 2015
win 10 x64