跳至内容

Call of Imported Functions

导入函数的调用

在mql4程序的执行过程中,客户端终端使用早期绑定来导入函数。这意味着如果程序调用了某个导入的函数,相应的模块(ex4或dll)会在程序加载时加载。MQL4和DLL库在调用模块的线程中执行。

不建议使用完全指定的模块名称来加载,例如Drive:\Directory\FileName.Ext。MQL4库从terminal_dir\MQL4\Libraries文件夹中加载。如果找不到该库,客户端终端会尝试从terminal_dir\experts文件夹中加载它。

系统库(DLL)由操作系统规则加载。如果库已经加载(例如,另一个专家顾问,甚至是从另一个并行运行的客户端终端),则使用对已加载库的请求。否则,按以下顺序进行搜索:

  1. 导入dll的模块启动的目录。这里的模块可以是专家顾问、脚本、指标或EX4库;
  2. terminal_data_directory\MQL4\Libraries目录(TERMINAL_DATA_PATH\MQL4\Libraries);
  3. MetaTrader 4客户端终端启动的目录;
  4. 系统目录;
  5. Windows目录;
  6. 当前目录;
  7. PATH系统变量中列出的目录。

如果DLL库在其工作中使用了另一个DLL,则在没有第二个DLL的情况下无法加载第一个DLL。

在专家顾问(脚本、指标)被加载之前,会形成一个所有EX4库模块的通用列表。这个列表既会被加载后的专家顾问(脚本、指标)使用,也会被此列表中的库使用。因此,需要一次性加载许多次使用的EX4库模块。库使用专家顾问(脚本、指标)调用的预定义变量

导入的EX4库按以下顺序搜索:

  1. 相对于导入EX4的专家顾问(脚本、指标)目录的路径;
  2. terminal_directory\MQL4\Libraries目录;
  3. 所有MetaTrader 4客户端终端的共同目录中的MQL4\Libraries目录(Common\MQL4\Libraries)。

将DLL导入mql4程序时,必须确保Windows API调用的一致性。为了确保这种一致性,在用C或C++编写的程序的源代码中,使用Microsoft(r)编译器特有的关键字__stdcall。这种一致性的特点如下:

  • 调用者(在我们的案例中是一个mql4程序)应该“看到”被调用的函数的原型(从DLL导入的),以便正确地将参数堆叠起来;
  • 调用者(在我们的案例中是一个mql4程序)以相反的顺序将参数放入堆栈——按照这个顺序,导入的函数读取传递给它的参数;
  • 参数按值传递,除非明确按引用传递(在我们的案例中是字符串);
  • 导入的函数独立地通过读取传递给它的参数来清理堆栈。

在描述导入函数的原型时,可以使用默认参数。

如果相应的库无法加载,或者禁止使用DLL,或者找不到导入的函数——专家顾问会在日志文件中的“专家顾问停止”消息中停止运行。在这种情况下,专家顾问将不会运行,直到重新初始化。专家顾问可以通过重新编译或打开其属性表并按下OK来重新初始化。

传递参数

所有简单类型的参数都按值传递,除非明确说明按引用传递。当传递字符串时,传递的是复制后字符串的缓冲区地址;如果字符串按引用传递,则直接传递该字符串的缓冲区地址而不进行复制。

包含动态数组、字符串、类、其他复杂结构以及枚举对象的静态或动态数组结构不能作为参数传递给导入的函数。

当向DLL传递数组时,总是传递数据缓冲区的起始地址(无论是否设置了AS_SERIES标志)。DLL内的函数对AS_SERIES标志一无所知,传递的数组是未定义长度的静态数组;应使用额外参数来指定数组大小。

最后更新于