Проблема при работе c kernel.32.dll из MQL4

 

Вот код тестового эксперта

//+------------------------------------------------------------------+
//|                                                      testIni.mq4 |
//|                                                         olyakish |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "olyakish"
#property link      ""
#include <IniFiles.mqh>
string Param,str;
 
int start()
  {
   Param=StringConcatenate("Param",1);
   Print("Param=",Param);
   str=ReadIniString("c:\1234.ini","start", Param,"");
   Print ("str=",str);
   Param=StringConcatenate("Param",2);
   Print("Param=",Param);
   str=ReadIniString("c:\1234.ini","start", Param,"");
   Print ("str=",str);
   Param=StringConcatenate("Param",3);
   Print("Param=",Param);
   str=ReadIniString("c:\1234.ini","start", Param,"");
   Print ("str=",str);   
   return(0);
  }
//+------------------------------------------------------------------+

Предполагается наличие IniFiles . mqh из codebase

А также файла 1234.ini в корневом коталоге диска "С"

Содержание данного файла

[start]
Param1=11111###USD###2###2###1
Param3=33333###GBP###1###3###1


Фрагмемт журнала из тестера


23:44:22 testIni EURUSD,H1: loaded successfully
23:44:22 testIni started for testing
23:44:22 2004.06.22 15:00 testIni EURUSD,H1: Param=Param1
23:44:22 2004.06.22 15:00 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:00 testIni EURUSD,H1: Param=Param2
23:44:22 2004.06.22 15:00 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:00 testIni EURUSD,H1: Param=Param3
23:44:22 2004.06.22 15:00 testIni EURUSD,H1: str=33333###GBP###1###3###1
23:44:22 2004.06.22 15:05 testIni EURUSD,H1: Param=Param1
23:44:22 2004.06.22 15:05 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:05 testIni EURUSD,H1: Param=Param2
23:44:22 2004.06.22 15:05 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:05 testIni EURUSD,H1: Param=Param3
23:44:22 2004.06.22 15:05 testIni EURUSD,H1: str=33333###GBP###1###3###1
23:44:22 2004.06.22 15:10 testIni EURUSD,H1: Param=Param1
23:44:22 2004.06.22 15:10 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:10 testIni EURUSD,H1: Param=Param2
23:44:22 2004.06.22 15:10 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:10 testIni EURUSD,H1: Param=Param3
23:44:22 2004.06.22 15:10 testIni EURUSD,H1: str=33333###GBP###1###3###1
23:44:22 2004.06.22 15:15 testIni EURUSD,H1: Param=Param1
23:44:22 2004.06.22 15:15 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:15 testIni EURUSD,H1: Param=Param2
23:44:22 2004.06.22 15:15 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:15 testIni EURUSD,H1: Param=Param3
23:44:22 2004.06.22 15:15 testIni EURUSD,H1: str=33333###GBP###1###3###1
23:44:22 2004.06.22 15:30 testIni EURUSD,H1: Param=Param1
23:44:22 2004.06.22 15:30 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:30 testIni EURUSD,H1: Param=Param2
23:44:22 2004.06.22 15:30 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:30 testIni EURUSD,H1: Param=Param3
23:44:22 2004.06.22 15:30 testIni EURUSD,H1: str=33333###GBP###1###3###1
23:44:22 2004.06.22 15:35 testIni EURUSD,H1: Param=Param1
23:44:22 2004.06.22 15:35 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:35 testIni EURUSD,H1: Param=Param2
23:44:22 2004.06.22 15:35 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:35 testIni EURUSD,H1: Param=Param3
23:44:22 2004.06.22 15:35 testIni EURUSD,H1: str=33333###GBP###1###3###1
23:44:22 2004.06.22 15:40 testIni EURUSD,H1: Param=Param1
23:44:22 2004.06.22 15:40 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:40 testIni EURUSD,H1: Param=Param2
23:44:22 2004.06.22 15:40 testIni EURUSD,H1: str=11111###USD###2###2###1
23:44:22 2004.06.22 15:40 testIni EURUSD,H1: Param=Param3
23:44:22 2004.06.22 15:40 testIni EURUSD,H1: str=33333###GBP###1###3###1



Тоесть получается что если не находится параметр Param2 в ини файле результат должен был бы быть "", а не предыдущее считанное значение

Подскажите где проблема

В самой dll или же это особенности/странности MQL4

 
olyakish:

...
Подскажите где проблема

В самой dll или же это особенности/странности MQL4


Подобные странности связаны с функцией GetPrivateProfileStringA,
экспортируемой из kernel32.dll.

В случае, если Вы сначала попытаетесь считать несуществующий параметр из *.ini файла, а потом следом - существующий, н-р,

...
 Param=StringConcatenate("Param",2);
 Print("Param=",Param);
 str=ReadIniString("c:\1234.ini","start", Param,"");
 Print ("str=",str);
 Param=StringConcatenate("Param",1);
 Print("Param=",Param);
 str=ReadIniString("c:\1234.ini","start", Param,"");
 Print ("str=",str);
...
то все будет работать нормально. Если наоборот, как написано у Вас, то функция GetPrivateProfileStringA упорно
будет возвращать предыдущий считанный параметр.

Причиной такого странного поведения функции является параметр Default. Для корректной работы в обоих указанных
выше случаях данный строковый параметр нельзя инициализировать строкой без символов, т.е. как у Вас: Default = "".

Лучше передавать строку с пустым символом: Default = " ".

Я обычно употребляю такую инициализацию: Default = "Key is not found".
Ваш код в этом случае выглядел бы так:
//+------------------------------------------------------------------+
//|                                                      testIni.mq4 |
//|                                                         olyakish |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "olyakish"
#property link      ""
#include <IniFiles.mqh>
string Param,str;
string Default = "Key is not found";
 
int start()
  {
   Param=StringConcatenate("Param",1);
   Print("Param=",Param);
   str=ReadIniString("c:\1234.ini","start", Param, Default);
   Print ("str=",str);
   Param=StringConcatenate("Param",2);
   Print("Param=",Param);
   str=ReadIniString("c:\1234.ini","start", Param, Default);
   Print ("str=",str);
   Param=StringConcatenate("Param",3);
   Print("Param=",Param);
   str=ReadIniString("c:\1234.ini","start", Param, Default);
   Print ("str=",str);   
   return(0);
  }
//+------------------------------------------------------------------+
Фрагмент журнала из тестера:
...
21:05:49 1999.03.09 18:30 testIni EURUSD,M30: Param=Param1
21:05:49 1999.03.09 18:30 testIni EURUSD,M30: str=11111###USD###2###2###1
21:05:49 1999.03.09 18:30 testIni EURUSD,M30: Param=Param2
21:05:49 1999.03.09 18:30 testIni EURUSD,M30: str=Key is not found
21:05:49 1999.03.09 18:30 testIni EURUSD,M30: Param=Param3
21:05:49 1999.03.09 18:30 testIni EURUSD,M30: str=33333###GBP###1###3###1
21:05:49 1999.03.09 19:00 testIni EURUSD,M30: Param=Param1
21:05:49 1999.03.09 19:00 testIni EURUSD,M30: str=11111###USD###2###2###1
21:05:49 1999.03.09 19:00 testIni EURUSD,M30: Param=Param2
21:05:49 1999.03.09 19:00 testIni EURUSD,M30: str=Key is not found
21:05:49 1999.03.09 19:00 testIni EURUSD,M30: Param=Param3
21:05:49 1999.03.09 19:00 testIni EURUSD,M30: str=33333###GBP###1###3###1
...
 
Ilnur:
...
Спасибо Вам, очень оригинально.
 

Вот часть кода эксперта, который из example.ini:

[common]
numCross=3

[cross1]
name=EURUSD

[cross2]
name=GBPUSD

[cross3]
name=USDJPY


читает кол-во пар и потом поочередно в массив of string сохраняет названия пар:

#include <IniFiles.mqh>

extern string config_path = "C:\Program Files\MetaTrader - MetaQuotes\experts\example.ini";

string CrossName[];
int numCross=0;
//+------------------------------------------------------------------+
//| expert initialization function |
//+------------------------------------------------------------------+
int init()
{
string sectionName = "common";

numCross = ReadIniInteger(config_path, sectionName, "numCross", 0);
ArrayResize(CrossName, numCross);

for (int i=0; i<numCross; i++)
{
sectionName = StringConcatenate("cross", i+1);
CrossName[i] = ReadIniString(config_path, sectionName, "name", "-");
// CrossName[i] = StringSubstr(ReadIniString(config_path, sectionName, "name", "-"), 0, 0);
Print("init.1: CrossName[", (i+1), "]=", CrossName[i]);
}
Print("init.1: read complete");

for (i=0; i<numCross; i++)
{
Print("init.2: CrossName[", (i+1), "]=", CrossName[i]);
}


Print("-------------------------------");
for (i=0; i<numCross; i++)
{
sectionName = StringConcatenate("cross", i+1);
CrossName[i] = StringSubstr(ReadIniString(config_path, sectionName, "name", "-"), 0, 0);
Print("init.3: CrossName[", (i+1), "]=", CrossName[i]);
}
Print("init.3: read complete");

for (i=0; i<numCross; i++)
{
Print("init.4: CrossName[", (i+1), "]=", CrossName[i]);
}

return(0);
}


вроде бы все просто и после прочтения ini мы должны получить массив имен пар.

Но в результате после очередного чтения параметра из ini и присваивания очередному элементу массива значения,

все остальные ранее присвоенные элементы получают тоже самое значение.

2009.04.09 02:17:06 example GBPUSD,H4: init.4: CrossName[3]=USDJPY
2009.04.09 02:17:06 example GBPUSD,H4: init.4: CrossName[2]=GBPUSD
2009.04.09 02:17:06 example GBPUSD,H4: init.4: CrossName[1]=EURUSD
2009.04.09 02:17:06 example GBPUSD,H4: init.3: read complete
2009.04.09 02:17:06 example GBPUSD,H4: init.3: CrossName[3]=USDJPY
2009.04.09 02:17:06 example GBPUSD,H4: init.3: CrossName[2]=GBPUSD
2009.04.09 02:17:06 example GBPUSD,H4: init.3: CrossName[1]=EURUSD
2009.04.09 02:17:06 example GBPUSD,H4: -------------------------------
2009.04.09 02:17:06 example GBPUSD,H4: init.2: CrossName[3]=USDJPY
2009.04.09 02:17:06 example GBPUSD,H4: init.2: CrossName[2]=USDJPY
2009.04.09 02:17:06 example GBPUSD,H4: init.2: CrossName[1]=USDJPY

2009.04.09 02:17:06 example GBPUSD,H4: init.1: read complete
2009.04.09 02:17:06 example GBPUSD,H4: init.1: CrossName[3]=USDJPY
2009.04.09 02:17:06 example GBPUSD,H4: init.1: CrossName[2]=GBPUSD
2009.04.09 02:17:06 example GBPUSD,H4: init.1: CrossName[1]=EURUSD

Получается, что при присваивании переменной строкового массива значения фактически происходит присвоение

ссылки а не значения. Просмотрел всю доступную документацию плюс форум, но ответа почему это так не нашел.

Выход нашел через использование StringSubstr, но что-то подсказывает, что это не совсем парвильно.


Вопроск тем, кто знает:как правильно элементам массива строк присваивать значения других переменных?

Причина обращения: