MQL4基础教程:编译预处理详解
预定义常量
编译控制
文件包含
函数导入
预处理程序是MQL4编译程序中的一个特殊组成部分,其作用是在程序正式编译之前预先准备好源代码。通过预处理,可以显著提升程序源码的可读性和组织性。在MQL4程序中,借助包含指定文件的方式可以获得结构清晰的源码,同时为常量赋予易于记忆的名称也有助于增强代码的可理解性。
此外,预处理程序还允许MQL4程序定义特定的参数,以满足不同的编译需求。当“#”号位于程序的第一行时,该行即为预处理程序的控制指令。需要注意的是,预处理程序指令以回车换行作为结束标志。
预定义常量
使用 #define 命令,可以在程序中定义符号名或符号常量来代表特定的字符串。随后,编译程序会将所有符号名替换为对应的字符串。实际上,这些名称可以被任意文本替换,并不局限于数字,例如:
#define identifier value
常量符号名的命名规则与变量名相同,其值可以是以下任意类型:
#define ABC 100
#define PI 0.314
#define COMPANY_NAME "myEAtrade Inc."
...
void ShowCopyright()
{
Print("版权所有 © 2001-2007, ",COMPANY_NAME);
Print("http://www.myeatrade.com");
}
编译控制
每个MQL4程序允许指定额外的特定参数,这些参数通过“#property”命名,不需要用户明确启动程序,即可帮助客户端提供合适的服务。需要注意的是,这一功能还与技术指标的外部设定有关。
#property 识别值及描述:
- link: 公司网站的相关连接
- copyright: 公司名称
- stacksize: 堆栈大小
- library: 库
- indicator_chart_window: 在图表窗口显示指标
- indicator_separate_window: 在独立显示窗口显示指标
- indicator_buffers: 计算指标的缓冲区个数,最大为8
- indicator_minimum: 独立显示的指标窗口下端缩放比例
- indicator_maximum: 独立显示的指标窗口上端缩放比例
- indicator_colorN: 线1到线8的显示颜色
- indicator_widthN: 线1到线8的显示宽度
- indicator_styleN: 线1到线8的显示样式
- indicator_levelN: 自定义指标的第N条水平线(N为1到8)
- indicator_levelcolor: 自定义指标的第N条水平线颜色(N为1到8)
- indicator_levelwidth: 自定义指标的第N条水平线宽度(N为1到8)
- indicator_levelstyle: 自定义指标的第N条水平线样式(N为1到8)
- show_confirm: 在脚本运行之前显示确认框
- show_inputs: 在脚本运行之前显示它的属性表;禁用show_confirm属性
示例:
#property link "http://www.myeatrade.com"
#property copyright "myEAtrade Inc."
#property library
#property stacksize 1024
在所执行模块的设置中,编译程序将会保存这些已说明的值。
文件包含
#include 命令行可以放置在程序的任意部分,但通常所有的“文件包含”都统一放置在源代码的开头。调用格式如下:
#include
#include "file_name";
示例:
#include
#include "mylib.mqh"
预处理程序将用WinUser32.mqh文件的内容替换这一行。尖括号表示WinUser32.mqh文件将会从默认目录调用(通常默认目录为terminal_directory/experts/include),且不会搜索当前目录。
如果文件名用引号括起来,将在当前目录中搜索该文件(源码主文件所在位置),而不会搜索标准目录。
函数导入
函数可以从MQL4编译过的模块(*.EX4文件)和操作系统文件模块(*.DLL文件)中导入。模块名需要在#import指令中指定。由于编译程序能够以适当的方式生成被导入函数的调用和传递参数,因此函数的完整说明是必需的。函数说明要紧跟在 #import "module name" 命令后面,并以新的#import命令(不带参数)结束导入函数说明块。
#import "file_name"
func1 define;
func2 define;
...
funcN define;
#import
导入函数必须有唯一的名称,相同名称的函数无法从不同的模块同时导入。导入的函数名称不能与那些内置函数冲突。
由于导入函数是在模块之外编译的,编译程序无法检查参数传递的正确性。这就是为什么为了避免运行时错误,有必要精确地说明参数类型定义和参数顺序的原因。传递到导入函数(从EX4和从DLL模块)的这些参数不能通过默认值获得值。
示例:
#import "user32.dll"
int MessageBoxA(int hWnd, string lpText, string lpCaption, int uType);
#import "stdlib.ex4"
string ErrorDescription(int error_code);
int RGB(int red_value, int green_value, int blue_value);
bool CompareDoubles(double number1, double number2);
string DoubleToStrMorePrecision(double number, int precision);
string IntegerToHexString(int integer_number);
#import "Expert示例.dll"
int GetIntValue(int);
double GetDoubleValue(double);
string GetStringValue(string);
double GetArrayItemValue(double arr[], int, int);
bool SetArrayItemValue(double& arr[], int,int, double);
double GetRatesItemValue(double rates[][6], int, int, int);
int SortStringArray(string& arr[], int);
int ProcessStringArray(string& arr[], int);
#import
对于在MQL4程序执行期间导入的函数,采用了所谓的“后期联编”。这就意味着只要导入的函数未被调用,相应的模块(EX4或DLL)就不会被加载。
不推荐使用全路径文件名(如Drive:/Directory/FileName.Ext)加载模块。MQL4库会从terminal_dir/experts/libraries文件夹中载入进来。如果没有找到库,就会尝试从terminal_dir/experts文件夹中加载。
