Скачать MetaTrader 5

Вызов импортируемых функцих со строковыми параметрами?

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Forex Trader
114269
Forex Trader  
Есть такой скрипт:

#include <stdlib.mqh>
#include <winuser32.mqh>
#import "user32.dll"
int GetClassNameA(int hWnd, string lpClassName, int nMaxCount);
#import

int start()
{

	int h = WindowHandle(Symbol(), Period()); 
	string s;
	s = "123456789012345678901234567890";
	Print(s);
	int len = StringLen(s);
	GetClassNameA(h, s, len);
	Print(s);
	s = "123456789012345678901234567890";
	Print(s);
	return (0);
}



Этот скрипт должен получить имя класса окна в переменную s.
Правильно ли я это делать?
Тут возникает следующая проблема.
Класс получается корректно, но последующие попытки присвоить переменной s другое значение средствами MQL заканчиваются безрезультатно. Значение не меняется.
Вот что выдаёт такой скрипт в логи:

19:36:01 SendMessage EURUSD,M30: 123456789012345678901234567890
19:36:01 SendMessage EURUSD,M30: AfxFrameOrView42
19:36:01 SendMessage EURUSD,M30: AfxFrameOrView42

А должен выдавать:
19:36:01 SendMessage EURUSD,M30: 123456789012345678901234567890
19:36:01 SendMessage EURUSD,M30: AfxFrameOrView42
19:36:01 SendMessage EURUSD,M30: 123456789012345678901234567890

Если в самом начале переменную s не инициализировать, то в неё значение вообще не возвращается.
Уважаемые разработчики, можете ли Вы указать как правильно вызывать такие импортируемые методы?
Т.е. те, в которые в качестве параметра передаётся (char*).

Forex Trader
114269
Forex Trader  
В данном случае произошло вот что:

Вы назначили переменной s статическую строку, которая находится в пуле стрингов и не может быть изменена. При этом функция GetClassName естественно ничего не знает про какой-то там пул стрингов, ей дали область памяти, она туда записала.

Поэтому попробуйте присвоить переменной временную строку. Например так:

s = "123456789012345678901234567890";
s = s + " ";

Кстати, если бы Вы присвоили во второй раз переменной s какое-либо другое значение, то Вы бы и не увидели проблему.
Forex Trader
114269
Forex Trader  
Если в начале присвоить переменной s временную строку, то тогда функция GetClassName вообще не изменяет значение переменной (может и изменяет, но я этого не вижу).
Тогда возникает такой вопрос:
Каким образом можно корректно выделить буфер для таких вызовов?
И какое значение мне надо передавать в качестве nMaxCount (размера буфера)?
Когда строка находится в пуле строк, какой объём памяти для этого выделяется? Равный длине строки (может +1) или 255?
Когда строка передаётся в функцию, что на самом деле передаётся? Адрес начала строки? Каким образом после вызова определяется новый размер строки? Судя по хелпу, длина строки храниться вместе с адресом буфера.
Forex Trader
114269
Forex Trader  
Я получу ответ на свой вопрос?
Forex Trader
114269
Forex Trader  
При вызове любых функций параметры передаются по значению, то есть формируются их локальные копии. Это же касается и строк. Исключение составляют константные строки, которые изначально располагаются в так называемом строковом пуле. Так как эта строка неудаляемая, то и копии её не создаётся. Но при вызове dll-функции такая строка портится (что и было показано Вашим примером).

Что делать? Не использовать такие строки (передающиеся в качестве принимающего параметра) для других целей.
Forex Trader
114269
Forex Trader  
Т.е., насколько я понял, если мне надо делать вызов функций из dll, которые возвращают строки, то лучше всю логику работы с этими строками реализовать в dll. А в MQL передавать лишь числовые значения.
Я правильно понял?
Или всё таки можно как-то вернуть в MQL строку из dll, например, не через параметр, а через возвращаемое значение?
Forex Trader
114269
Forex Trader  
Можно возвращать строки. Посмотрите наш пример ExpertSample.dll, функция GetStringValue
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий