问题
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
int
flags = 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 ofMessageBox()
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