二进制格式库的开发和连接
除了特殊类型的 MQL 程序 - EA 交易、 指标、 脚本和服务之外 MetaTrader 5 平台允许你创建和连接具有任意功能的独立二进制模块,这些模块被编译为符合 Windows 标准的 ex5 文件或常用的 dll(动态链接库)。它们可以是分析算法、图形可视化、与 web 服务的网络交互、外部程序的控制或操作系统本身。在任何情况下,这类库在终端中不是作为独立的 MQL 程序工作,而是与上述 4 种类型中的任何一种协同工作。
集成函数库和主(父)程序的思路是,库导出某些函数,即声明它们可供外部使用,然后程序导入它们的原型。正是原型的描述 - 名称集、参数列表和返回值 - 这样您就可以在代码中调用这些函数,而不需要实现它们。
然后,在 MQL 程序启动期间,执行早期动态链接。这意味着在主程序之后加载库,并在库中导入的原型和导出函数之间建立对应关系。通过名称、参数列表和返回类型建立一对一的对应关系是成功加载的先决条件。如果没有为至少一个函数的导入说明找到相应的导出实现,MQL 程序的执行将被取消(程序在启动阶段报错并结束)。
MQL 程序与库通信组件图
启动 MQL 程序时,不能选择包含的库。此链接是由开发人员在库导入时编译主程序期间设置的。但是,用户可以在程序启动之间用另一个 ex5/dll 文件手动替换原先的文件(假设实现的导出函数的原型在库中匹配)。例如,如果库包含带标签的字符串资源,这可以用于切换用户界面语言。然而,库通常作为一种商业产品提供,因此作者不准备以开放头文件的形式发布。
对那些从其他环境转到 MQL5 并且已经熟悉 DLL 技术的程序员,我们想补充一则关于后期动态链接的说明,也是 DLL 的一个优点。在执行过程中,一个 MQL 程序(或 DLL 模块)不可能完全动态连接到另一个 MQL 程序。唯一类似的操作是 MQL5 允许你在此期间通过 iCustom 或者 IndicatorCreate 链接 EA 交易和指标,其中指标充当动态链接库(但是,与之进行的编程交互必须通过指标 API 来完成,这意味着与直接函数调用(通过 export/#import)相比,CopyBuffer 的开销会增加)。
注意,在正常情况下,当从源代码编译 MQL 程序而不导入外部函数时,使用静态链接,即生成的二进制代码直接引用被调用的函数,因为这些函数在编译时是已知的。
严格地说,一个库也可以依赖其他库,即它可以导入一些函数。从理论上讲,这种依赖关系链甚至可以更长:例如,MQL 程序包含库 A,库 A 使用库 B,而库 B 又使用库 C。但是,不建议使用这种依赖链,因为这会导致产品的分发和安装变得复杂,并且使潜在启动问题原因的确认变得更加困难。因此,库通常直接连接到父 MQL 程序。
在本章中,我们将描述在 MQL5 中创建库、导出和导入函数(包括对函数中使用的数据类型的限制)以及连接外部(现成)DLL 的过程。本书未涵盖 DLL 开发方面的内容。