[{"data":1,"prerenderedAt":112},["ShallowReactive",2],{"\u002F2014-07-01-mql4%E8%BF%9E%E6%8E%A5dll%E7%9A%84%E7%AE%80%E5%8D%95%E5%B0%9D%E8%AF%95":3},{"id":4,"title":5,"body":6,"date":90,"description":12,"extension":91,"meta":92,"navigation":95,"path":107,"seo":108,"stem":109,"tags":110,"__hash__":111},"blogs\u002F_legacy\u002F2014\u002F2014-07-01-mql4%e8%bf%9e%e6%8e%a5dll%e7%9a%84%e7%ae%80%e5%8d%95%e5%b0%9d%e8%af%95.md","Mql4连接DLL的简单尝试",{"type":7,"value":8,"toc":86},"minimark",[9,13,16,19,30,33,39,42,48,51,57,60,63,70,73,83],[10,11,12],"p",{},"作为Mt4自动交易和指标的脚本语言的Mql4功能虽然已经很强大，但是还是有不少先天的缺陷。为了弥补这些，同时为了补足本身运行环境限制，Mql4提供了连接Dll运行的功能。",[10,14,15],{},"一般情况下不会用到这个功能，如果只是要处理报价数据的话，在Mql4中比较方便。但是出于保护代码防止破解、监视系统运行状态、从网络获取资源解析等特殊目的。还是会需要用到Dll的外部扩展的，由于近期不太可能用到，所以只是简单的尝试一下，了解一下大致过程的程度。",[10,17,18],{},"首先是Dll方面，以Vc6为例，新建一个Dll项目。所有配置都不用修改，保持默认即可。对代码简洁性比较敏感的童鞋可以选择把预编译头之类的去掉。具体的文件结构可以参考末尾提供的工程文件。Dll的接口暴露是在.def文件中定义的，Mql4的数据结构定义可以在官方的示例和帮助文档中找到：",[20,21,26],"pre",{"className":22,"code":24,"language":25},[23],"language-text","\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F\u002F \n#define WIN32_LEAN_AND_MEAN \n#define MT4_EXPFUNC __declspec(dllexport)\n\n#pragma pack(push,1) \nstruct RateInfo{ \n    unsigned int ctm; \n    double open; \n    double low; \n    double high; \n    double close; \n    double vol; \n};\n\nstruct Mqlstr{ \n   int      size;       \u002F\u002F 32-bit integer, contains size of the buffer, allocated for the string. \n   LPWSTR   buffer;     \u002F\u002F 32-bit address of the buffer, containing the string. \n   int      reserved;   \u002F\u002F 32-bit integer, reserved. \n};\n\n#pragma pack(pop)\n","text",[27,28,24],"code",{"__ignoreMap":29},"",[10,31,32],{},"在这里只做简单的尝试，从Mql4中传入字符串并用MessageBox输出。",[20,34,37],{"className":35,"code":36,"language":25},[23],"MT4_EXPFUNC void __stdcall Hello(WCHAR *say, int tilen) \n{    \n    std::stringstream ts; \n    \n    ts \u003C\u003C tilen; \n    ts \u003C\u003C \"||\"; \n    \n    for(;tilen>0;--tilen){ \n        ts \u003C\u003C (char*)say; \n        ++say; \n    }\n\n    MessageBox(NULL, ts.str().c_str(), \"hello\", NULL); \n}\n",[27,38,36],{"__ignoreMap":29},[10,40,41],{},"这边有个问题，官方的示例中没有明示。Mql4传递过来的是WCHAR的指针，但是其与C++的字符串处理似乎稍有不兼容。所以最后采用了传入字符串长度，并使用Stream读入的解决方案。由于是WCHAR，需要做一些简单的处理，如果不留心的话会出现不可预知的错误。",[20,43,46],{"className":44,"code":45,"language":25},[23],"#include \u003CTestMql.mqh>\n\u002F\u002F+------------------------------------------------------------------+\n\u002F\u002F| Custom indicator initialization function                         |\n\u002F\u002F+------------------------------------------------------------------+\nint OnInit()\n{\n\u002F\u002F--- indicator buffers mapping\nstring ts = \"Hello, world\";\nHello(ts, StringLen(ts));\n\u002F\u002F---\nreturn(INIT_SUCCEEDED);\n}\n",[27,47,45],{"__ignoreMap":29},[10,49,50],{},"在Mt4中采用上面的方式调用即可，TestMql.mqh的内容如下。通常大的项目才会采用这样的形式，如果没有什么特殊需求也可以直接把这些内容复制到上面去：",[20,52,55],{"className":53,"code":54,"language":25},[23],"#import \"TestMql.dll\"\nvoid Hello(string,int);\n#import\n",[27,56,54],{"__ignoreMap":29},[10,58,59],{},"#import就是做DLL导入的MQL4语句，注意保持闭合和提供正确的函数原型。",[10,61,62],{},"上面的代码运行结果如下：",[10,64,65],{},[66,67],"img",{"alt":68,"src":69},"image","\u002Fwp-content\u002Fuploads\u002F2014\u002F07\u002Fimage_thumb.png",[10,71,72],{},"到此所有的连接工作就完成了。上面的VC代码打包在度娘网盘处：",[10,74,75,76,82],{},"链接: ",[77,78,79],"a",{"href":79,"rel":80},"http:\u002F\u002Fpan.baidu.com\u002Fs\u002F1bnb8JfT",[81],"nofollow"," 密码: qgor",[10,84,85],{},"MQL4代码就是上面那些，直接新建指标，复制粘贴即可。",{"title":29,"searchDepth":87,"depth":88,"links":89},2,3,[],"2014-07-01","md",{"layout":93,"status":94,"published":95,"author":96,"author_login":97,"author_email":98,"author_url":99,"wordpress_id":100,"wordpress_url":101,"date_gmt":102,"excerpt":103},"post","publish",true,{"display_name":97,"login":97,"email":98,"url":99},"chaoshikari","chaoshikari@gmail.com","\u002F",878,"\u002F\u002F?p=878","2014-07-01 14:58:00 +0000",{"type":7,"value":104},[105],[10,106,12],{},"\u002F2014-07-01-mql4连接dll的简单尝试",{"title":5,"description":12},"_legacy\u002F2014\u002F2014-07-01-mql4%e8%bf%9e%e6%8e%a5dll%e7%9a%84%e7%ae%80%e5%8d%95%e5%b0%9d%e8%af%95",[],"5ynPWMowdpx7ZBCHWTS53kmq8otZ7bc5Q7mE85mcw40",1788763183779]