用 EX5 库封装与共享代码:导出函数、隐藏类实现、可被继承
当你写出好用的函数或类,想共享给团队或对外发布,又不想公开实现细节——EX5 库就是 MQL5 的答案。编译进 .ex5 后,调用方只能看到接口、看不到源码。本文从“导出/导入函数”讲起,再到“把整个类的实现藏进库里”,最后到“库类还能被外部继承”,一步步把封装与共享讲透。
一、函数的导出与导入
导出函数要满足三件事:源文件扩展名必须是 .mq5(不是 .mqh)才能编进 .ex5;文件里加 #property library 预处理指令;在函数声明前加 export 关键字。编译后得到 library.ex5,其中的 libfunc 就能被别的程序用。导入则靠 #import 指令:在目标文件里写 #import "library.ex5" 然后声明函数原型,编译器会在 MQL5\Libraries 文件夹找 .ex5,找不到就写相对路径。
// library.mq5 —— 带 #property library 与 export
#property library
int libfunc(int a, int b) export
{
int c=a+b;
Print("a+b="+string(c));
return(c);
}
// uses.mq5 —— 导入并使用
#import "library.ex5"
int libfunc(int a, int b);
#import
void OnStart() { libfunc(1,2); }
二、实战:把 GUI 绘图函数做成库
文中用一个 Graph.mq5 库示范:它导出在图表上画按钮、编辑框、标签、矩形标签的函数(如 SetEdit、SetLabel、SetButton、HideChart),目标 EA(Spiro.mq5)只需 #import "Graph.ex5" 声明原型就能直接调用,把绘图细节完全藏进库。这正是一开始说的价值:共享能力、隐藏实现。函数不仅能导入 .mq5,也能导入 .mqh,方便做成公共头。
三、类实现怎么藏:接口类 + 虚函数
MQL5 不能直接 export 一整个类,于是作者用“多态 + 虚函数”绕过去:把类拆成两个——公开的接口类(如 CSpiro,只留变量和虚函数声明,放在 .mqh 头文件)和隐藏的实现类(ISpiro,继承 CSpiro,真正实现全在 .ex5 里)。再导出一个工厂函数 iSpiro() export,返回一个 new ISpiro 实例。调用方拿到的类型是 CSpiro*,永远触不到 ISpiro 的具体代码。
- 公开接口类(CSpiro):变量 + 虚函数声明,放 .mqh 头文件,调用方可见
- 隐藏实现类(ISpiro):继承 CSpiro,真正实现细节全在 .ex5 内
- 工厂函数 iSpiro() export:返回 new ISpiro,调用方只拿到 CSpiro*
- 关键:所有对外函数都要加 virtual,才能通过接口正确分发到实现
四、导出类的继承:库类也能被扩展
MetaQuotes 后来支持了“直接继承 ex5 库里的类”,这是更进一步的玩法。意味着你发布的库类,别人可以像普通类一样派生出子类、重写虚函数,而不必知道内部实现。这让 EX5 库从“黑盒工具”变成“可扩展框架”——适合做插件体系或平台级 SDK。
// 接口头 Spiro.mqh(公开)
class CSpiro
{
public:
string m_sID; int m_x0,m_y0; color m_clr;
double m_R,m_r,m_D,m_dAlfa,m_nRotate;
CSpiro() {}; ~CSpiro() {};
virtual void Init(int ax0,int ay0,color aclr,string asID) { };
virtual void SetData(double aR,double ar,double aD,double adA,double an) { };
};
// 隐藏实现 ISpiro.mq5 里:CSpiro *iSpiro() export { return(new ISpiro); }
五、EX5 库的发布与注意事项
发布库时,把 .ex5 与公开 .mqh 头一起交给调用方,.ex5 里的实现就是黑盒。要注意:导出/导入有官方限制(如参数类型支持范围、字符串传递方式),写之前务必查文档的“导出/导入”章节。另外 .ex5 是编译产物,跨平台/跨版本 MT5 要注意兼容性——同一编译环境产出最稳。
六、小结
EX5 库是 MQL5 里“共享但不暴露”的标准机制:函数用 #property library + export 导出、#import 导入;类用“公开接口类(虚函数)+ 隐藏实现类 + 工厂函数 iSpiro()”把实现藏进 .ex5,还能被外部继承扩展。它把你的专有算法变成黑盒 SDK,是团队分工与对外授权的利器。记住导入签名要严丝合缝、发布时附带公开头文件,封装就能既安全又顺手。