How to call a function from a DLL file from [ MQL5 ] code?

Deadly 提交于 2019-12-23 02:38:07

问题


Why the first MessageBox() works and the second doesn't?

I don't know where the problem is.

Does the MQL5 can access the dll file?

I need to to call C# functions that read JSON.

No errors appear in MetaEditor.

C# .dll file:

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;
    }
}
}

this is an MQL5 code:

#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 );
    }

回答1:


Welcome to the
Wild
Worlds of MQL

How to test a DLL-function call access?

This is the easiest part. Test it from inside DLL. Add some input/output parameters/values printing on stdout into each DLL-function source and during the debugging-phase you have all the needed C#-side self-diagnostics covered there.

MQL-side also needs to have all DLL-calls permitted, check the MetaTrader Terminal 5 settings:
[x] Allow DLL imports ....


Syntax matters: check calling-signature(s) item by item

MQL documentation states a single, clear call-signature for MessageBox() to be used:

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

Parameters :
text: [in] Text, containing message to output.

caption= NULL : [in] Optional text to be displayed in the box header. If the parameter is empty, Expert Advisor name is shown in the box header.

flags= 0 : [in] Optional flags defining appearance and behavior of a message box. Flags can be a combination of a special group of flags. ( Plus: Default value == 0 == MB_OK )

Return Value :
If the function is successfully performed, the returned value is one of values of MessageBox() return codes. ( Which are: { IDOK | IDCANCEL | IDABORT | IDRETRY | IDIGNORE | IDYES | IDNO | IDTRYAGAIN | IDCONTINUE } )


MQL is not C#
MQL-string is not a string in fact, but a struct
MQL is not forgiving any single tiny detail:
due care is a must:

MQL documentation states:

Internal representation of the string type is a structure of 12 bytes long:

#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)

This is The Strange Answer to why the first call worked.
The MessageBox() did not try to access any memory location on it's call, as the faked MQL-string-struct (ill)-declared by itself, via the .size struct-component it's own .buffer memory area ( addressed indirectly ) to have 0 bytes in length and thus no memory area ( ultimately colliding, by definition, with an address space of some other memory-object ) will be, in this specific case accessed.

After more than a decade in MQL domain, with more than a few hundreds man*years hands-on team experience with creeping MQL language-syntax, I may dare state, "do not rely on no errors being reported in a compilation phase", MetaTrader Terminal has made us hair-less in many circumstances, even when the code was following published documentation word-by-word.

Feel free to check other posts on MQL to see more details on DLL-integration nightmares and also good stories about going into distributed processing, GPGPU-computing et al.


Final remark on JSON

If I were to design an architecture to communicate via JSON I would jump in with ZeroMQ DLL distributed-processing services, that would make your goal much faster, than building just another JSON-parser as a greenfield project.



来源:https://stackoverflow.com/questions/36861487/how-to-call-a-function-from-a-dll-file-from-mql5-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!