如何从 [ MQL5 ] 代码的 DLL 文件调用函数



为什么第一个MessageBox()有效而第二个无效?

我不知道问题出在哪里。

MQL5可以访问dll文件吗?

我需要调用读取JSON C#函数。

元编辑器中未显示任何错误。

C# .dll文件:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
namespace TestMe
{
    class Test
    {
   // [DllExport("Add", CallingConvention = CallingConvention.StdCall)]
    public static int Add(int left, int right)
    {
        return left + right;
    }

    public static int Sub(int left, int right)
    {
        return left - right;
    }

    public static double AddDouble(double left, double right)
    {
        return left + right;
    }

    public static float AddFloat(float left, float right)
    {
        return left + right;
    }
}
}

这是一个MQL5代码:

#import "TestMe.dll"
                    int    Add(       int    left, int    right );
                    int    Sub(       int    left, int    right );
                    float  AddFloat(  float  left, float  right );
                    double AddDouble( double left, double right );
#import
#property strict                 // MQL-syntax-mode-modifier == "strict"
int OnInit()
{   int k = 0;
    MessageBox( k );             // this call works
    k = Add( 1, 666 );
    MessageBox( k );             // Doesn't work
    return( INIT_SUCCEEDED );
    }

欢迎来到
MQL的狂野
世界

如何测试 DLL 函数调用访问?

这是最简单的部分。 从内部测试它 DLL .将一些stdout输入/输出参数/值添加到每个DLL函数源中,在调试阶段,您将涵盖所有需要的C#端自诊断。

MQL端还需要允许所有DLL调用,请检查MetaTrader终端5设置:
[x] Allow DLL imports ...


语法问题:逐项检查呼叫签名

MQL文档声明了要使用的MessageBox()的单个、清晰的呼叫签名:

int MessageBox(
string text , // message text
string caption = NULL , // box header
int flags = 0 ); // defines set of buttons in the box


Parameters : text : [in]文本,包含要输出的消息。

caption = NULL : [in] 要在框标题中显示的可选文本。如果参数为空,则"EA 交易"名称显示在框标题中。

flags = 0 : [in] 定义消息框的外观和行为的可选标志。标志可以是一组特殊标志的组合。 (加号:默认值 == 0 == MB_OK

Return Value :
如果函数成功执行,则返回值是MessageBox()返回代码的值之一。分别是{ IDOK | IDCANCEL | IDABORT | IDRETRY | IDIGNORE | IDYES | IDNO | IDTRYAGAIN | IDCONTINUE }


MQL不是 C#
MQL-string 实际上不是string,而是struct
MQL不会原谅任何微小的细节:必须注意

MQL文档指出:

字符串类型的内部表示形式是长度为 12 个字节的结构:

#pragma pack(push,1) 
struct MqlString 
  { 
   int      size;       // 32-bit integer, contains size of the buffer, allocated for the string. 
   LPWSTR   buffer;     // 32-bit address of the buffer, containing the string. 
   int      reserved;   // 32-bit integer, reserved. 
  }; 
#pragma pack(pop,1)

这就是第一个调用成功的原因The Strange Answer
MessageBox()没有尝试访问它调用的任何内存位置,因为伪造的 MQL 字符串结构 (ill) 通过 .size 结构组件自己声明它自己的.buffer内存区域(间接寻址)长度为 0 字节,因此没有内存区域(根据定义,最终与其他一些内存对象的地址空间冲突)将是, 在此特定情况下访问。

经过MQL领域的十多年,拥有超过几百人*多年的实践经验,在爬行MQL语言语法方面,我敢说,"不要依赖在编译阶段没有报告错误"MetaTrader 终端在许多情况下使我们变得无毛,即使代码逐字逐句地遵循已发布的文档。

请随时查看 MQL 上的其他帖子,了解有关 DLL 集成噩梦的更多详细信息,以及有关进入分布式处理、 GPGPU -computing 等的好故事。


最后要说JSON

如果我要设计一个通过JSON进行通信的架构,我会跳入ZeroMQ DLL分布式处理服务,这将使你的目标更快,而不是仅仅构建另一个 JSON 解析器作为绿地项目。

相关内容

  • 没有找到相关文章

最新更新