在不同终端中运行的两个EA之间交换数据 - 页 3

 

Еще можно попробовать забить гвоздь лампочкой. У некоторых получается.

这种方法有什么问题?

你还可以设置系统时间。

这就是系统时间同步的方式:-)。不是通过设定,而是通过阅读。这是一种数据交换

 




大家好!

可靠连接终端的最佳方式之一似乎是使用网络1C。
两个主要特点:
1.主要应用程序在1C上执行,终端及其MQL4程序是执行者,
2.主要应用程序在其中一个终端上执行,1C应用程序被用作链接协议。

优点:
1.能够在不同服务器上同时存储和处理全部报价历史;
2.

 
Andres >> :

我已经写了一个小库,我的专家顾问已经在通过注册表改变信息。事实上,它们是通过寄存器改变的,我在磁盘上没有看到任何读写操作。


谢谢你提供的图书馆!我也会处理这个交换的实施问题。

立刻就有一个明显的问题。你是如何实现读/写参数检查的?也就是说,另一个EA如何知道某个键的某个参数已经可以被读取?

你是否通过另一个EA创建了一些额外的读/写权限键,或者是有一些其他的功能你已经测试过了?也就是说,换句话说,你如何提供对一个参数的统一访问,使EA不在同一时间对同一关键参数工作,以避免失败?

 

我有点想明白了,你是如何提供对关键参数的统一访问的。你只需使用字符串GetErrorString( int ErrorCode)函数检查错误。

而在出错的情况下,你必须重复操作。但我不明白在库中哪里进行了这种重复操作。也许我必须自己补充一些需要的东西。总之,感谢你提供了很好的解决方案!

 

这是在Win API之上的一个简单的包装器,有错误输出,只允许你用字符串的关键参数工作。

GetErrorString( int ErrorCode )相当具有指示性,因此当错误发生时,你知道是什么,在哪里,为什么以及如何解决。当然,我们可以也应该把对错误的处理放到包装器和库函数的边界之外,并根据不同专家的使用键的逻辑,以不同的方式对它们做出反应(有许多类型的错误)。同时,在任何失败的尝试中,SetStringValue()只能告诉你,尝试失败。而GetStringValue(),在失败的情况下,不仅会告诉你,还会返回一个空字符串。我认为不需要额外的读/写权限键,因为这种检查是由操作系统完成的。错误处理 和适当的错误响应就足够了。我的 "热 "测试的EA只是在时间上不同步,这可能就是为什么它们在同一时间读/写一个字段时没有冲突。但这当然不是一个解决方案。我们需要继续前进。但我还是在一个晚上写的,不要对它进行太严厉的评价。一种 "betta "版本,以感受方法:-)。

 
Andres >> :

我已经写了一个小库,我的EA已经在通过注册表改变信息。事实上,它们是通过RAM改变的,没有读写到磁盘,我没有观察到。在MSDN中写到,最好不要把超过几百Kb的数据塞进注册表。

库的配置方式是,所有的键和参数都是在临时注册表区域创建的,不会写入永久注册表。重新启动后,这些钥匙就不见了。

一个BUT,该库只适用于字符串参数,长度不超过255个字符(MQL的限制)。但这已经很足够了。一般来说,注册表中的参数可以是不同的类型,而不仅仅是字符串,但在我看来,现在还不需要其他类型。现在我有两个通过注册表交换的EA,但可能需要更多:-)。另一个好处是,在Win API中,它可以连接到网络注册表。如果有人需要在同一网络中不同计算机上运行的EA之间交换信息,他们可以从这个方向寻找。在我看来,它是快速、简单和可靠的,而且没有任何dlls和文件。输入一个字符串,输出一个字符串。

安德烈,谢谢你!

为我略加编辑和修饰。

也许你应该把这个放在你的储蓄 罐里?相当于,一个有价值的解决方案!

附加的文件:
reglib.rar  11 kb
 

总有一天我会把你的库,Andrey,和我的 整合起来,以处理图形变量。这将使我的变量声明多了一个层次。

1.会有一个GlobalSuperVariable。这样的变量将在操作系统层面上可见。

2.现在有了GlobalVariable

3.还有GlobalChartVariable。它们只对一个窗口可见。

一般来说,它应该产生一个库,用于在MQL4的操作系统级别上处理其结构。

 
Zhunko >> :

1.会有一个GlobalSuperVariable。这种变量将在操作系统层面上可见。

如果你把这样的变量上传到kodobase,我将非常感激(可能我不是唯一的一个)。

厌倦了用自制的方法来编造它。

 

向安德鲁提问。这个登记册会不会延续下去?

string GetStringValue1 (int    hKey,      // Код ключа реестра.
                        int    lpSize,    // Длина считываемой строки.
                        string ValueName) // Имя параметра ключа.
 {
  int lpType[1];      // Возвращаемый тип параметра.
  int lpcbData[1];    // Размер буфера.
  int i;              // Переменная для подрезки последних пустых строк.
  int lres;           // Результат.
  string lpData = ""; // Буфер для возвращаемой строки.
  //----
  lpcbData[0] = lpSize; // Размер буфера.
  for ( i = 0; i < lpSize; i++) lpData = lpData + "#";
  lres = RegQueryValueExA ( hKey, ValueName, 0, lpType, lpData, lpcbData); // вызов API
  // Теперь в lpcbData[0] размер скопированных байт. Проверяем результат.
  if ( lres != ERROR_SUCCESS)
   {
    Print ("Error in RegQueryValueExA(): ", GetErrorString ( lres));
    return ("");
   }
  if ( lpType[0] == REG_SZ || lpType[0] == REG_EXPAND_SZ) return (StringSubstr ( lpData, 0, lpcbData[0] - 1));
  return ("");
 }
 
我来解释一下。问题是,如果你用一个动态递增的字符串作为缓冲区,会有一些错误。我自己以前也曾偶然发现过一个。
InitRegDefines();
hKey = CreateKey( HKEY_CURRENT_USER, "!MT4TestKey" );

// заносим
SetStringValue( hKey, "Param", "Test" );

// вытаскиваем при помощи Вашей функции:
Print( GetStringValue1( hKey, 20, "Param" ) );

在那之后,它变成了。

2009.05.19 01:22:16 2008.12.31 01:49 temp EURUSD,M1: ####
2009.05.19 01:22:16 2008.12.31 01:49 temp EURUSD,M1: RegCreateKeyExA(): 一个不存在的分区被创建。
2009.05.19 01:22:16 开始测试的临时程序

也就是说,缓冲区的内容不会改变,尽管在调用时没有错误。而它是注册表中的 "测试 "行。

我从论坛 的帖子中了解到,它的发生是因为一些奇怪的字符串从MQL环境传递到DLL函数。在MQL环境中,开发人员使用他们自己的管理器(字符串池)对字符串进行操作,显然,在这个边界上,错误的缓冲区被填充,因此我们无法看到API-函数返回的结果。但如果我们使用初始化为整个最大长度的字符串,那么,就我所见,就没有问题了。这就是为什么有255个字符的 "#"字符串的原因。选择 "#"字符只是为了让眼睛看到这个字符串。这与Win API本身没有关系,因为在调用之前,缓冲区被填满了什么并不重要。这就是我前面提到的字符串长度限制。你可以向SetStringValue()传递超过255个字符的字符串,但不可能读取它们。

当然,没有限制是好事,但我不认为这有什么大的不便。这就引出了一个问题:为什么你需要读取一个特定大小的字符串?如果是关于约束,你可以通过编写一个函数将输入的字符串分成N个长为255的参数+"余数 "参数来绕过它们。而在阅读时,它又把它收集起来。没有其他办法。如果你有困难,请与我联系,我会做到的。只是每个人的需求不同,你不可能提供所有的东西,对我来说只有这些就足够了,有人使用全局变量,甚至在几个层面上。