How to pass argument by reference from MQL4 to C++ DLL

折月煮酒 提交于 2020-01-22 20:17:28

问题


I am trying to write a simple program in MQL4 which passes a variable to a C++ DLL function by reference and prints the updated variable value in MQL4. Given below is my code.

DLL function:

void Test(int* X)
{
    *X = 6;
}

MQL4 Code

#import "Test.dll"
void Test(int&);
#import

void OnStart()
{
  int A;
  Test(A);
  Alert(A);
}

But I am not getting any value back from C++ function for variable A. Can someone please help me what I am doing wrong here?

Thanks in advance


回答1:


Let's start with the DLL-side:

int TestMoreApproachesAtONCE( int *X,
                              int *Y,
                              int  Z
                              )
{
    *X = 6;                   // 6 assigned to a 4B-memory chunk ref'd by *X
     Y = 6;                   // 6 assigned to a variable  Y
     return( Z );             // Z returned as a value passed from Caller
}

MQL4 requires DLL to have:

Functions imported DLL into a mql4-program must ensure the Windows API calls agreement. To ensure such an agreement, in the source text of programs written in C or C++, use the keyword __stdcall, which is specific to the Microsoft(r) compilers. This agreement is characterized by the following:

· caller (in our case it is a mql4-program) should "see" a prototype of a function called (imported from the DLL), in order to properly combine parameters to a stack;

· caller (in our case it is a mql4-program) puts parameters to the stack in a reverse order, from right to left - in this order an imported function reads parameters passed to it;

· parameters are passed by value, except those explicitly passed by reference (in our case strings)

· an imported function cleans the stack independently by reading parameters passed to it.

When describing the prototype of an imported function, default parameters can be used.

If the corresponding library is unable to load, or there is a prohibition on the DLL use, or the imported function is not found - the Expert Advisor stops its operation with the appropriate message "Expert Advisor stopped" in the Journal (log file). In this case the Expert Advisor will not run until it is reinitialized. An Expert Advisor can be reinitialized as a result of recompilation or after the table of its properties is opened and OK is pressed.

Now demonstrate the MQL4 side:

#import    "Test.dll" // -----------------------------------------------

                         void Test( int& );

                         int  TestMoreApproachesAtONCE( int &X,
                                                        int &Y,
                                                        int  Z
                                                        );
#import // "Test.dll" // -----------------------------------------------    

void OnStart()
{
     int A = EMPTY,
         B = EMPTY,
         C = EMPTY;
  // ---------------------------------------------------<PRE>
     Print( " TEST:: inital values are: A = ", A,
                                      " B = ", B,
                                      " C = ", C
                                      );
  // ---------------------------------------------------<TEST>

     C = TestMoreApproachesAtONCE( A, B, 6 );

  // ---------------------------------------------------<POST>
     Print( " TEST::  final values are: A = ", A,
                                      " B = ", B,
                                      " C = ", C
                                      );

}

Anyway, enjoy the Wild Worlds of MQL4 -- Also may enjoy to click and read other posts on issues in MQL4/DLL integration and/or signalling/messaging in MQL4 domains. Feel free to ask more

Finally, MQL4 Documentation states:

Passing Parameters
All parameters of simple types are passed by values unless it is explicitly indicated that they are passed by reference. When a string is passed, the address of the buffer of the copied string is passed; if a string is passed by reference, the address of the buffer of this string without copying it is passed to the function imported from DLL.

Structures that contain dynamic arrays, strings, classes, other complex structures, as well as static or dynamic arrays of the enumerated objects, can't be passed as a parameter to an imported function.

When passing an array to DLL, the address of the beginning of the data buffer is always passed (irrespective of the AS_SERIES flag). A function inside a DLL knows nothing about the AS_SERIES flag, the passed array is a static array of an undefined length; an additional parameter should be used for specifying the array size.



来源:https://stackoverflow.com/questions/39520941/how-to-pass-argument-by-reference-from-mql4-to-c-dll

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