MetaTrader + C++:DLL

MetaTrader + C++:DLL

MetaTrader 可以调用从 Windows DLL 导出的函数。当 Expert Advisor 或指标需要更易于用 C 或 C++ 维护的代码、需要访问原生库,或者需要比纯脚本实现更好的性能时,这会很有用。

要点很简单:

  • 从 DLL 导出普通的 C 风格函数。
  • 使用 MetaTrader 期望的正确调用约定。
  • 让 MQL 参数类型与原生函数签名匹配。
  • 在运行脚本、指标或 Expert Advisor 之前,在 MetaTrader 中启用 DLL 导入。

C++ DLL 示例

一个最小的 C++ DLL 可以像这样暴露函数:

// mt_example.cpp
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

extern "C" __declspec(dllexport) int __stdcall Add(int a, int b)
{
    return a + b;
}

extern "C" __declspec(dllexport) double __stdcall Multiply(double a, double b)
{
    return a * b;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
{
    return TRUE;
}

extern "C" 会防止 C++ 名称修饰,因此 MetaTrader 可以按名称找到导出的函数。__declspec(dllexport) 使函数在 DLL 外部可见。__stdcall 通常用于由 MQL 导入的函数。

构建 DLL 时要使用与 MetaTrader 终端相同的架构。32 位终端需要 32 位 DLL,64 位终端需要 64 位 DLL。

MQL 导入示例

编译 DLL 后,将它放在 MetaTrader 可以加载的位置,通常是终端的 MQL4/LibrariesMQL5/Libraries 目录。

对于 MQL4:

#import "mt_example.dll"
int Add(int a, int b);
double Multiply(double a, double b);
#import

void OnStart()
{
   int sum = Add(2, 3);
   double product = Multiply(1.5, 4.0);

   Print("sum = ", sum);
   Print("product = ", product);
}

对于 MQL5,同样的思路也适用:

#import "mt_example.dll"
int Add(int a, int b);
double Multiply(double a, double b);
#import

void OnStart()
{
   int sum = Add(2, 3);
   double product = Multiply(1.5, 4.0);

   Print("sum = ", sum);
   Print("product = ", product);
}

常见检查项

如果 MetaTrader 无法调用 DLL,请先检查这些项目:

  1. 已在终端以及脚本、指标或 Expert Advisor 设置中启用 DLL 导入。
  2. DLL 位于正确的 Libraries 目录中。
  3. DLL 架构与终端架构匹配。
  4. 导出的函数名没有被修饰。使用 dumpbin /exports mt_example.dll 或 Dependency Walker 等工具检查导出项。
  5. MQL 声明与 C++ 函数签名完全匹配。

关于字符串和数组的说明

intdouble 等基本值最容易传递。字符串、数组和结构体需要更谨慎,因为内存所有权和布局必须与 MetaTrader 的预期一致。

传递字符串时,建议先使用一个小型测试函数,并在将其用于交易代码之前验证编码和缓冲区大小。传递数组时,要同时传入类似指针的参数和长度,并且绝不要假设 DLL 可以安全读取超出给定大小的内容。

实用规则

保持 DLL 接口小而稳定。让 MQL 处理交易逻辑和 MetaTrader 特定状态,而让 C++ DLL 处理隔离的原生工作,例如计算、与另一个原生库集成,或对性能敏感的处理。

Leave a Reply