本次测试基于vs2019商业版和MT5,操作系统为Windows10家庭版。
一、制作DLL库
选择动态链接库后点击下一步:
设置项目名称和保存位置,如图所示:
创建好项目后我们的解决方案中包含 如下:
头文件:framework.h、pch.h
源文件:dllmain.cpp、pch.cpp
在此基础上我们添加自己的类接口:MyInterface.h和MyInterface.cpp
在我们的pch.h文件中,添加一句代码:
#define _DLLAPI extern "C" __declspec(dllexport)
这句代码的意思是定义一个宏,_DLLAPI,该符号会被替换成extern "C" __declspec(dllexport);
extern "C" 指定使用C语言的编译和链接规范
__declspec(dllexport)指定函数或数据项在编译时导出到动态链接库的扩展属性,告诉编译器将函数或数据项作为DLL的可见部分导出,以便其他程序可以访问。
在我们的MyInterface.h文件中做函数声明:
#pragma once
#include "pch.h"
#include <iostream>
_DLLAPI int __stdcall Add(const int a, const int b);
_DLLAPI int __stdcall Sub(const int a, const int b);
_DLLAPI int __stdcall Mul(const int a, const int b);
_DLLAPI int __stdcall Div(const int a, const int b);
__stdcall是一个函数调用约定关键字
指定函数在被调用和返回时参数传递和堆栈清理的方式
遵循以下约定:
1、函数参数从右向左依次压入堆栈
2、被调用函数负责清理堆栈上的参数
3、函数的返回值通常存储在EAX寄存器中
优点:
1、保证兼容性,确保代码与Windows操作系统和其他库之间的兼容性
2、明确函数参数传递方式和堆栈清理责任,提高代码可读性和可维护性
3、在DLL中确保函数接口的一致
4、c和c++之间的相互操作性,帮助在c++代码中调用c函数时进行正确的参数传递和堆栈清理
在我们的MyInterface.cpp文件中实现函数:
#include "pch.h"
#include "MyInterface.h"
int Sub(const int a, const int b)
{
return a - b;
}
int Mul(const int a, const int b)
{
return a * b;
}
int Div(const int a, const int b)
{
if (b == 0)
{
std::cout << "error: b can't be zero!" << std::endl;
return -1;
}
return a / b;
}
鼠标右键MT5API后点击属性:
找到:常规->输出目录后将目录设置为MT5的Libraries目录下:
解决方案选择x64位,点击:生成->生成解决方案:
此时我们可以在MT5的Libraries目录下发现动态库:
二、使用DLL库
如果你的MT5中Libraries目录下没有显示任何文件,则如下图操作:
在MT5中新建一个脚本:
//+------------------------------------------------------------------+
//| test01.mq5 |
//| Copyright 2023, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#import "MT5API.dll"
int Add(const int a, const int b);
int Sub(const int a, const int b);
int Mul(const int a, const int b);
int Div(const int a, const int b);
#import
void OnStart()
{
int ret=-1;
int a=10,b=20;
string text=NULL;
ret=Add(a,b);
printf("The result of "+a+" + "+b+"is:"+ret);
ret=Sub(a,b);
printf("The result of "+a+" - "+b+"is:"+ret);
ret=Mul(a,b);
printf("The result of "+a+" * "+b+"is:"+ret);
ret=Div(a,b);
printf("The result of "+a+" / "+b+"is:"+ret);
}
编写后运行,在MT5的专家中输出信息:
至此,我们已经可以使用自己封装好的DLL库了!!!
三、遇到的问题
1、将输出目录设置在MT5的Libraries目录下避免了每次更改DLL库都需要将DLL文件复制到Libraries目录下;
2、一定要将解决方案平台设置位x64!!!目前MT5仅协同64位函数库操作,如果你选择的是x86的平台,在使用时会给出错误信息: