Что-то не помню я, чтобы в Делфи значение по ссылке передавались
с синтаксисом на сях. А в примере с массивом вообще без ссылок
передается, поэтому ничего и не возвращается.
Выдели строку заданной длинныв эксперте на MQL и в неё уже записывай
строку в DLL по указателю PChar.
Так же ты НЕ сможешь принимать в DLL как динамический массив str1: array of Integer. Возможно либо так str1: PInteger, либо str1: PDouble
Массивы в коде эксперта на MQL объявляешь либо заданной длинны либо изменением размера массива ArrayResize до нужного значения.
Память не выделяй для массивов в DLL указатель на которые хочешь передать в эксперт. Создание и задание размера массива следует
производить в тексе MQL эксперта.
Обмениваться массивами данных желательно через указатель (в эксперте это double[] либо double&[]). Я в эксперте привожу Integer к элементам Double массива, а в DLL наоборот элемены массива Double к Interger так же можно и с Char. Вероятно можно и массивы Integer передавать но у меня не получалось что то.
Так же ты НЕ сможешь принимать в DLL как динамический массив str1: array of Integer. Возможно либо так str1: PInteger, либо str1: PDouble
Массивы в коде эксперта на MQL объявляешь либо заданной длинны либо изменением размера массива ArrayResize до нужного значения.
Память не выделяй для массивов в DLL указатель на которые хочешь передать в эксперт. Создание и задание размера массива следует
производить в тексе MQL эксперта.
Обмениваться массивами данных желательно через указатель (в эксперте это double[] либо double&[]). Я в эксперте привожу Integer к элементам Double массива, а в DLL наоборот элемены массива Double к Interger так же можно и с Char. Вероятно можно и массивы Integer передавать но у меня не получалось что то.
favoritefx:
Что-то не помню я, чтобы в Делфи значение по ссылке передавались с синтаксисом на сях. А в примере с массивом вообще без ссылок передается, поэтому ничего и не возвращается.
Извини, но я не понял, как ДИНАМЧЕСКИЙ массив без ссылки передается.
Вообщем, мне важно передать массив. Если не сложно напиши
пример. Я пойму.
Что-то не помню я, чтобы в Делфи значение по ссылке передавались с синтаксисом на сях. А в примере с массивом вообще без ссылок передается, поэтому ничего и не возвращается.
elritmo:
Выдели строку заданной длинны в эксперте на MQL и в неё уже записывай строку в DLL по указателю PChar.
Как можно выделить строку заданной длинны? Я так делалВыдели строку заданной длинны в эксперте на MQL и в неё уже записывай строку в DLL по указателю PChar.
string a = ""; string b = "12345";Если я правильно понял, то после этого: строка a имеет длинну 0, а строка b имеет длинну 5.
В DDL ничего не менял, там у меня строка str2 := 'qwert' имеет длинну 5, как и строка b.
library Ping;
function sum(const str1: PChar; var str2: PChar): PChar; stdcall;
begin
Result := PChar( string( str1 ) + string( str2 ) );
str2 := 'qwert';
end;
exports
sum;
begin
end.
Но ничего не поменялось. Так же, в такой конструкции (без указателя
&)function sum(const str1: PChar; var str2: PChar): PChar; stdcall;
begin
Result := PChar( string( str1 ) + string( str2 ) );
str2 := 'qwert';
end;
exports
sum;
begin
end.
#import "ping.dll" string sum(string str1, string str2); #importСтрока str2 возвращает кривые символы. Функция возвращает нормальное значение.
А в конструкции (с указателем &)
#import "ping.dll" string sum(string str1, string & str2); #importТерминал, также выдает критическую ошибку и вылетает. По спавке и по логике указатель & не надо ставить. А что делать, если не работает.
Может я не правильно код в Delphi пишу или направильно DLL создаю.
Ещё пробовал так
string b; ArrayResize(b, 5);Но так ошибку пишет и ArrayResize(b, 5) возвращает -1 (ошибка № 4065). В MQL4 string так длинну не меняет.
Может кто-нибудь из модераторов происнит по конкретнее как должно быть или, хотя бы, как у них тип string работает. А то ссылка на строку есть, а размера строки нет. Мне кажется из за размера все проблеммы.
elritmo:
...
Так же ты НЕ сможешь принимать в DLL как динамический массив str1: array of Integer. Возможно либо так str1: PInteger, либо str1: PDouble
...
После замены...
Так же ты НЕ сможешь принимать в DLL как динамический массив str1: array of Integer. Возможно либо так str1: PInteger, либо str1: PDouble
...
str1: array of Integer на str1: PDouble
Терминал перестал выдавть критическую ошибку и все заработало. Но вот вопрос как я с таким типом PDouble
буду с массивом работать и ещё надо его изменить. Я не знаю, расскажи.
...
Массивы в коде эксперта на MQL объявляешь либо заданной длинны либо изменением размера массива ArrayResize до нужного значения.
...
Вот так делалМассивы в коде эксперта на MQL объявляешь либо заданной длинны либо изменением размера массива ArrayResize до нужного значения.
...
double a[2] = {1, 2}; double b[2] = {3, 4};Вроде, правильно.
...
Память не выделяй для массивов в DLL указатель на которые хочешь передать в эксперт. Создание и задание размера массива следует
производить в тексе MQL эксперта.
...
Я так и делаю.Память не выделяй для массивов в DLL указатель на которые хочешь передать в эксперт. Создание и задание размера массива следует
производить в тексе MQL эксперта.
...
...
Обмениваться массивами данных желательно через указатель (в эксперте это double[] либо double&[])...
Обмениваться массивами данных желательно через указатель (в эксперте это double[] либо double&[])...
#import "ping.dll" double sum(double a[], double & b[]); #importЕщё хочу уточнить. Если я хочу массив изменить в DLL и сохранить его измененным после выполнения функции, то указатель & нужен ИЛИ нет?
В справке есть пример и там он стоит.
Вот пример из справки
Справочник MQL4 - Основы языка - Препроцессор - Импорт функций
#import "ExpertSample.dll" int GetIntValue(int); double GetDoubleValue(double); string GetStringValue(string); double GetArrayItemValue(double arr[], int, int); bool SetArrayItemValue(double& arr[], int,int, double); double GetRatesItemValue(double rates[][6], int, int, int); int SortStringArray(string& arr[], int); int ProcessStringArray(string& arr[], int); #importУ меня если после string ставить указатель &, то всегда происходит критическая ошибка. Что будет в таком случае "double& arr[]" даже не знаю, потому что с массивами вообще не получается работать. Но хотелось бы узнать.
Может у меня терминал ошибочный или даже в справке не правильно написано???
Ещё забыл сказать. Если пишите "истину", то не поленитесь
примерчик написать или отрывки кода (как на MQL4 так и на языке,
на котором DLL написана). Вот.
Пожалуйста. :)
Пожалуйста. :)
Попробуй вот так сделать
MQL4 код
#import "ping.dll"
void sum(string str1, string str2, string res_str);
#import
string
void init() {
str1 = "string1 "; str2 = "string2";
for(int i = 0; i < MAX_LENGTH; i++) // Длина MAX_LENGTH должна быть больше либо равна суммарной длине str1 и str2
res_str = res_str + " ";
sum(str1, str2, res_str);
}
Dll код
library Ping;
procedure sum(str1, str2, res_str : PChar); stdcall;
begin
StrCpy(res_str, PChar( string( str1 ) + string( str2 ) );
Суть в том что мт4 уже передал res_str - массива char с нулём на конце длиной MAX_LENGTH и тебе надо просто скопировать все элементы -
результат сложения string( str1 ) + string( str2 ) в эту строку не создавая новой. То есть теперь вместо некоторых пробелов будет строка - результат сложения.
end;
exports
sum;
begin
end
Есть ещё метод - ты в функции sum выделяешь память для строки и возвращаешь PChar а в MQL4 советнике присваиваешь результатsum переменной типа string. Затем в deinit вызываешь Dll функцию которой передаёшь этот эту пеерменную стринг на удаление. То есть в длл произойдёт удаление массива по переданному указателю на эту строку.
MQL4 код
#import "ping.dll"
void sum(string str1, string str2, string res_str);
#import
string
void init() {
str1 = "string1 "; str2 = "string2";
for(int i = 0; i < MAX_LENGTH; i++) // Длина MAX_LENGTH должна быть больше либо равна суммарной длине str1 и str2
res_str = res_str + " ";
sum(str1, str2, res_str);
}
Dll код
library Ping;
procedure sum(str1, str2, res_str : PChar); stdcall;
begin
StrCpy(res_str, PChar( string( str1 ) + string( str2 ) );
Суть в том что мт4 уже передал res_str - массива char с нулём на конце длиной MAX_LENGTH и тебе надо просто скопировать все элементы -
результат сложения string( str1 ) + string( str2 ) в эту строку не создавая новой. То есть теперь вместо некоторых пробелов будет строка - результат сложения.
end;
exports
sum;
begin
end
Есть ещё метод - ты в функции sum выделяешь память для строки и возвращаешь PChar а в MQL4 советнике присваиваешь результатsum переменной типа string. Затем в deinit вызываешь Dll функцию которой передаёшь этот эту пеерменную стринг на удаление. То есть в длл произойдёт удаление массива по переданному указателю на эту строку.
elritmo:
Попробуй вот так сделать
...
Попробовал (. Все по прежнему.Попробуй вот так сделать
...
Сделал все как ты написал. В результате переменная res_str не изменилась (как была из пробелов так и осталась).
Еще в твоем коде
Dll код
library Ping;
procedure sum(str1, str2, res_str : PChar); stdcall;
...
Переменная res_str не обозначена как var, (т.е. чтобы она сохранила свое значение после вызова функции
надо обязательно писать вар перед ее объявлением, в Delphi это
точно).library Ping;
procedure sum(str1, str2, res_str : PChar); stdcall;
...
Я сначало твой вариант попробывал и потом еще исправил так
Dll код
library Ping;
procedure sum(str1, str2: PChar; var res_str : PChar); stdcall;
и попробывал. Но ни в первом ни во втором случае не получается.
Максимум что получил - это каракули.library Ping;
procedure sum(str1, str2: PChar; var res_str : PChar); stdcall;
А у тебя этот пример работает или ты не проверял???
Может я кривой.
Я думаю проблема в моей DLL, так как она на Delphi написана, она по своему, наверно, с типами работает. Хотя числовые типы у меня все работают отлично!!!
Может кто-нибудь знающий приведет примерчик, любой самый простой.
elritmo:
Попробуй вот так сделать
...
А на счет массивов не подскажешь как быть. Также примерчиком.
Попробуй вот так сделать
...
А вообще, кто-нибудь из модераторов или из разрабодчиков мне
ответит, или мне надо письмо в тех. поддержку писать?
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
function sum(const str1: PChar; var str2: PChar): PChar; stdcall;
begin
Result := PChar( string( str1 ) + string( str2 ) );
str2 := 'qwert';
end;
exports
sum;
begin
end.
PChar = PAnsiChar - это по умолчанию.
Для этого пишу в коде советника следующее
И когда функция вызываеться, то проиисходит критическая ошибка и терминал вылетает.
Если убрать знак & перед str2
то, тогда результат есть, но str2 не меняет своего значения. А надо, что бы оно его изменило.
Еще хотел str2 представить в виде масива целых чисел и перенести, Вот так примерно
function sum(const str1: array of Integer; var str2: array of Integer): Integer; stdcall;
var
I: Integer;
begin
for I := 0 to 10 do
str2[I] := I; // эта запись толко как пример
Result := 0;
end;
exports
sum;
begin
end.
Но массив тоже не получилось изменить пишет ошибку и вылетает.
Пробывал сделать по разному, но получить измененую переменную str2 так и не получилось.
Иногда в ней в str2 непонятные значки записывались.
Вобщем, искал решение проблемы на форуме, но так и не нашел.
Напишите, пожалуйста, пример того как можно получить измененные параметры функции, конкретно строковые и массивы, остальные работают.
Хотелось бы, чтобы в документации про это написалибы побольше.