💻
用非托管导出在 MQL5 中调用 C# 代码
C#DLL非托管导出
托管与非托管代码的鸿沟
MetaTrader 的 MQL 可用 DLL 动态链接已有库,但只能直接调用“非托管”原生 DLL。C# 编译的程序集靠 CLR/CIL 运行,是“托管”的,MT5 无法用 LoadLibrary 直接调用,中间必须有一层导出包装。
解决方案:非托管导出
通过“非托管导出”(Unmanaged Export)或 C++/CLI 包装,把托管方法暴露为普通 C 函数,MT5 就能像调用普通 DLL 一样调用 C# 逻辑。
C# 侧 Calculator 类
先在 C# 里实现业务逻辑(如 Calculator.Add),再用 [DllExport] 或 C++/CLI 桥把它导出为 NativeExport_xxx_Add 这样的 C 接口。
// C# 计算逻辑
public class Calculator
{
public int Add(int a, int b) { return a + b; }
}
// 通过 [DllExport] 或 C++/CLI 包装导出
extern "C" __declspec(dllexport)
int NativeExport_CppCliWrapper_Calculator_Add(int a, int b)
{ return Calculator_Add(a, b); }
MQL5 侧调用
MQL5 用 #import 声明 DLL 函数并调用,就像调用任何原生库。返回值是普通 int/double,无托管痕迹。
#import "CppCliWrapper.dll" int NativeExport_CppCliWrapper_Calculator_Add(int a, int b); #import // 在 EA 中 int r = NativeExport_CppCliWrapper_Calculator_Add(3, 4);
关键注意
⚠ 部署三连
1) DLL 位数(32/64)必须与终端一致;2) 目标机需安装对应 .NET Runtime;3) 部署时把包装 DLL 与依赖一并分发到终端可访问目录。
小结
✦ 复用 .NET 生态
非托管导出让你复用 C# 的 JSON/ML/数据库等丰富生态,但 DLL 安全与依赖管理要管好,避免引入不可控的外部风险。
常见问题
MQL5 只支持原生非托管 DLL 调用,.NET 程序集需 CLR 托管,必须经过导出包装。
非托管导出(如 DllExport)直接标注托管方法;C++/CLI 写一层 C++ 桥,二者都能暴露 C 接口。
确保终端位数与 DLL 一致,目标机有对应 .NET 运行时,且 DLL 路径在终端可访问目录。